blob: 947b07315b3816de31e8ffe557f7a3f84dbd2dab [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! A dynamically-typed IoTDB cell value.
use super::TSDataType;
/// One cell of an IoTDB row: a typed scalar or `Null`.
///
/// `Date` carries an `i32` in `yyyyMMdd` form (e.g. 2026-07-10 →
/// `20260710`), matching the C#/Java wire encoding. `Timestamp` is epoch
/// milliseconds.
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
Boolean(bool),
Int32(i32),
Int64(i64),
Float(f32),
Double(f64),
Text(String),
Timestamp(i64),
/// Date as i32 `yyyyMMdd` (e.g. `20260710`).
Date(i32),
Blob(Vec<u8>),
String(String),
Null,
}
impl Value {
/// The [`TSDataType`] this value carries, or `None` for [`Value::Null`].
pub fn data_type(&self) -> Option<TSDataType> {
Some(match self {
Value::Boolean(_) => TSDataType::Boolean,
Value::Int32(_) => TSDataType::Int32,
Value::Int64(_) => TSDataType::Int64,
Value::Float(_) => TSDataType::Float,
Value::Double(_) => TSDataType::Double,
Value::Text(_) => TSDataType::Text,
Value::Timestamp(_) => TSDataType::Timestamp,
Value::Date(_) => TSDataType::Date,
Value::Blob(_) => TSDataType::Blob,
Value::String(_) => TSDataType::String,
Value::Null => return None,
})
}
/// The wire type code (§8 of the protocol spec), or `None` for `Null`.
pub fn type_code(&self) -> Option<i32> {
self.data_type().map(TSDataType::code)
}
/// True iff this is [`Value::Null`].
pub fn is_null(&self) -> bool {
matches!(self, Value::Null)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn type_codes() {
assert_eq!(Value::Boolean(true).type_code(), Some(0));
assert_eq!(Value::Int32(1).type_code(), Some(1));
assert_eq!(Value::Int64(1).type_code(), Some(2));
assert_eq!(Value::Float(1.0).type_code(), Some(3));
assert_eq!(Value::Double(1.0).type_code(), Some(4));
assert_eq!(Value::Text("t".into()).type_code(), Some(5));
assert_eq!(Value::Timestamp(0).type_code(), Some(8));
assert_eq!(Value::Date(20260710).type_code(), Some(9));
assert_eq!(Value::Blob(vec![0]).type_code(), Some(10));
assert_eq!(Value::String("s".into()).type_code(), Some(11));
assert_eq!(Value::Null.type_code(), None);
}
#[test]
fn data_type_of_null_is_none() {
assert_eq!(Value::Null.data_type(), None);
assert!(Value::Null.is_null());
assert!(!Value::Int32(7).is_null());
}
}