Skip to main content

qubit_datatype/datatype/
data_type.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # Data Type Definitions (Language Layer)
11//!
12//! Provides cross-module reusable common data type enum `DataType` and type mapping `DataTypeOf`.
13//!
14
15use std::fmt;
16use std::str::FromStr;
17
18use super::data_type_parse_error::DataTypeParseError;
19
20use serde::{
21    Deserialize,
22    Serialize,
23};
24
25/// Universal data type enumeration for cross-module type representation
26///
27/// Defines all basic data types and composite types supported by the system.
28/// This enum provides a unified way to represent and work with different data types
29/// across various modules and components.
30///
31/// `DataType` serves as a bridge between Rust's type system and runtime type
32/// information, enabling dynamic type handling, serialization, validation,
33/// and other type-aware operations.
34///
35/// # Features
36///
37/// - **Comprehensive Coverage**: Supports all basic Rust types plus common third-party types
38/// - **String Representation**: Each variant has a consistent string representation
39/// - **Serialization Support**: Implements `Serialize` and `Deserialize` for JSON/YAML support
40/// - **Type Mapping**: Works with `DataTypeOf` trait for compile-time type mapping
41///
42/// # Use Cases
43///
44/// - **Dynamic Type Handling**: Runtime type checking and conversion
45/// - **Serialization/Deserialization**: Type-aware data format conversion
46/// - **Validation Systems**: Type-based input validation
47/// - **Generic Programming**: Type-safe generic operations
48/// - **API Documentation**: Automatic type information generation
49///
50/// # Examples
51///
52/// ## Basic Usage
53///
54/// ```rust
55/// use qubit_datatype::DataType;
56///
57/// let data_type = DataType::Int32;
58/// assert_eq!(data_type.to_string(), "int32");
59/// assert_eq!(data_type.as_str(), "int32");
60/// ```
61///
62/// ## Type Checking
63///
64/// ```rust
65/// use qubit_datatype::DataType;
66///
67/// fn is_numeric(data_type: DataType) -> bool {
68///     matches!(data_type,
69///         DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 | DataType::Int128 |
70///         DataType::UInt8 | DataType::UInt16 | DataType::UInt32 | DataType::UInt64 | DataType::UInt128 |
71///         DataType::Float32 | DataType::Float64 | DataType::BigInteger | DataType::BigDecimal
72///     )
73/// }
74///
75/// assert!(is_numeric(DataType::Int32));
76/// assert!(!is_numeric(DataType::String));
77/// ```
78///
79/// ## Serialization
80///
81/// ```rust
82/// use qubit_datatype::DataType;
83/// use serde_json;
84///
85/// let data_type = DataType::Float64;
86/// let json = serde_json::to_string(&data_type).unwrap();
87/// assert_eq!(json, "\"float64\"");
88///
89/// let deserialized: DataType = serde_json::from_str(&json).unwrap();
90/// assert_eq!(deserialized, DataType::Float64);
91/// ```
92///
93///
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
95#[serde(rename_all = "lowercase")]
96pub enum DataType {
97    /// Boolean type
98    Bool,
99    /// Character type
100    Char,
101    /// 8-bit signed integer
102    Int8,
103    /// 16-bit signed integer
104    Int16,
105    /// 32-bit signed integer
106    Int32,
107    /// 64-bit signed integer
108    Int64,
109    /// 128-bit signed integer
110    Int128,
111    /// 8-bit unsigned integer
112    UInt8,
113    /// 16-bit unsigned integer
114    UInt16,
115    /// 32-bit unsigned integer
116    UInt32,
117    /// 64-bit unsigned integer
118    UInt64,
119    /// 128-bit unsigned integer
120    UInt128,
121    /// 32-bit floating point number
122    Float32,
123    /// 64-bit floating point number
124    Float64,
125    /// String type
126    String,
127    /// Date type (NaiveDate)
128    Date,
129    /// Time type (NaiveTime)
130    Time,
131    /// DateTime type (NaiveDateTime)
132    DateTime,
133    /// UTC time point (equivalent to Java Instant) (`DateTime<Utc>`)
134    Instant,
135    /// Big integer type (BigInt)
136    BigInteger,
137    /// Big decimal type (BigDecimal)
138    BigDecimal,
139    /// Platform-dependent signed integer (isize)
140    IntSize,
141    /// Platform-dependent unsigned integer (usize)
142    UIntSize,
143    /// Duration type (std::time::Duration)
144    Duration,
145    /// URL type (url::Url)
146    Url,
147    /// String map type (HashMap<String, String>)
148    StringMap,
149    /// JSON value type (serde_json::Value)
150    Json,
151}
152
153impl fmt::Display for DataType {
154    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
155        formatter.write_str(self.as_str())
156    }
157}
158
159impl FromStr for DataType {
160    type Err = DataTypeParseError;
161
162    fn from_str(value: &str) -> Result<Self, Self::Err> {
163        match value.to_ascii_lowercase().as_str() {
164            "bool" => Ok(DataType::Bool),
165            "char" => Ok(DataType::Char),
166            "int8" => Ok(DataType::Int8),
167            "int16" => Ok(DataType::Int16),
168            "int32" => Ok(DataType::Int32),
169            "int64" => Ok(DataType::Int64),
170            "int128" => Ok(DataType::Int128),
171            "uint8" => Ok(DataType::UInt8),
172            "uint16" => Ok(DataType::UInt16),
173            "uint32" => Ok(DataType::UInt32),
174            "uint64" => Ok(DataType::UInt64),
175            "uint128" => Ok(DataType::UInt128),
176            "float32" => Ok(DataType::Float32),
177            "float64" => Ok(DataType::Float64),
178            "string" => Ok(DataType::String),
179            "date" => Ok(DataType::Date),
180            "time" => Ok(DataType::Time),
181            "datetime" => Ok(DataType::DateTime),
182            "instant" => Ok(DataType::Instant),
183            "biginteger" => Ok(DataType::BigInteger),
184            "bigdecimal" => Ok(DataType::BigDecimal),
185            "intsize" => Ok(DataType::IntSize),
186            "uintsize" => Ok(DataType::UIntSize),
187            "duration" => Ok(DataType::Duration),
188            "url" => Ok(DataType::Url),
189            "stringmap" => Ok(DataType::StringMap),
190            "json" => Ok(DataType::Json),
191            _ => Err(DataTypeParseError::new(value)),
192        }
193    }
194}
195
196impl DataType {
197    // Keep explicit conversion helper for existing call-sites and API parity with
198    // current serialized/configuration text values.
199    /// Get the string representation of the data type.
200    ///
201    /// # Returns
202    ///
203    /// Returns the name string of the data type.
204    #[inline]
205    pub const fn as_str(&self) -> &'static str {
206        match self {
207            DataType::Bool => "bool",
208            DataType::Char => "char",
209            DataType::Int8 => "int8",
210            DataType::Int16 => "int16",
211            DataType::Int32 => "int32",
212            DataType::Int64 => "int64",
213            DataType::Int128 => "int128",
214            DataType::UInt8 => "uint8",
215            DataType::UInt16 => "uint16",
216            DataType::UInt32 => "uint32",
217            DataType::UInt64 => "uint64",
218            DataType::UInt128 => "uint128",
219            DataType::Float32 => "float32",
220            DataType::Float64 => "float64",
221            DataType::String => "string",
222            DataType::Date => "date",
223            DataType::Time => "time",
224            DataType::DateTime => "datetime",
225            DataType::Instant => "instant",
226            DataType::BigInteger => "biginteger",
227            DataType::BigDecimal => "bigdecimal",
228            DataType::IntSize => "intsize",
229            DataType::UIntSize => "uintsize",
230            DataType::Duration => "duration",
231            DataType::Url => "url",
232            DataType::StringMap => "stringmap",
233            DataType::Json => "json",
234        }
235    }
236}