Skip to main content

qubit_common/lang/
data_type.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # Data Type Definitions (Language Layer)
10//!
11//! Provides cross-module reusable common data type enum `DataType` and type mapping `DataTypeOf`.
12//!
13//! # Author
14//!
15//! Haixing Hu
16
17use bigdecimal::BigDecimal;
18use chrono::{
19    DateTime,
20    NaiveDate,
21    NaiveDateTime,
22    NaiveTime,
23    Utc,
24};
25use num_bigint::BigInt;
26use serde::{
27    Deserialize,
28    Serialize,
29};
30
31/// Universal data type enumeration for cross-module type representation
32///
33/// Defines all basic data types and composite types supported by the system.
34/// This enum provides a unified way to represent and work with different data types
35/// across various modules and components.
36///
37/// `DataType` serves as a bridge between Rust's type system and runtime type
38/// information, enabling dynamic type handling, serialization, validation,
39/// and other type-aware operations.
40///
41/// # Features
42///
43/// - **Comprehensive Coverage**: Supports all basic Rust types plus common third-party types
44/// - **String Representation**: Each variant has a consistent string representation
45/// - **Serialization Support**: Implements `Serialize` and `Deserialize` for JSON/YAML support
46/// - **Type Mapping**: Works with `DataTypeOf` trait for compile-time type mapping
47///
48/// # Use Cases
49///
50/// - **Dynamic Type Handling**: Runtime type checking and conversion
51/// - **Serialization/Deserialization**: Type-aware data format conversion
52/// - **Validation Systems**: Type-based input validation
53/// - **Generic Programming**: Type-safe generic operations
54/// - **API Documentation**: Automatic type information generation
55///
56/// # Examples
57///
58/// ## Basic Usage
59///
60/// ```rust,ignore
61/// use qubit_common::lang::DataType;
62///
63/// let data_type = DataType::Int32;
64/// assert_eq!(data_type.to_string(), "int32");
65/// assert_eq!(data_type.as_str(), "int32");
66/// ```
67///
68/// ## Type Checking
69///
70/// ```rust,ignore
71/// use qubit_common::lang::DataType;
72///
73/// fn is_numeric(data_type: DataType) -> bool {
74///     matches!(data_type,
75///         DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 | DataType::Int128 |
76///         DataType::UInt8 | DataType::UInt16 | DataType::UInt32 | DataType::UInt64 | DataType::UInt128 |
77///         DataType::Float32 | DataType::Float64 | DataType::BigInteger | DataType::BigDecimal
78///     )
79/// }
80///
81/// assert!(is_numeric(DataType::Int32));
82/// assert!(!is_numeric(DataType::String));
83/// ```
84///
85/// ## Serialization
86///
87/// ```rust,ignore
88/// use qubit_common::lang::DataType;
89/// use serde_json;
90///
91/// let data_type = DataType::Float64;
92/// let json = serde_json::to_string(&data_type).unwrap();
93/// assert_eq!(json, "\"float64\"");
94///
95/// let deserialized: DataType = serde_json::from_str(&json).unwrap();
96/// assert_eq!(deserialized, DataType::Float64);
97/// ```
98///
99/// # Author
100///
101/// Haixing Hu
102///
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
104pub enum DataType {
105    /// Boolean type
106    Bool,
107    /// Character type
108    Char,
109    /// 8-bit signed integer
110    Int8,
111    /// 16-bit signed integer
112    Int16,
113    /// 32-bit signed integer
114    Int32,
115    /// 64-bit signed integer
116    Int64,
117    /// 128-bit signed integer
118    Int128,
119    /// 8-bit unsigned integer
120    UInt8,
121    /// 16-bit unsigned integer
122    UInt16,
123    /// 32-bit unsigned integer
124    UInt32,
125    /// 64-bit unsigned integer
126    UInt64,
127    /// 128-bit unsigned integer
128    UInt128,
129    /// 32-bit floating point number
130    Float32,
131    /// 64-bit floating point number
132    Float64,
133    /// String type
134    String,
135    /// Date type (NaiveDate)
136    Date,
137    /// Time type (NaiveTime)
138    Time,
139    /// DateTime type (NaiveDateTime)
140    DateTime,
141    /// UTC time point (equivalent to Java Instant) (`DateTime<Utc>`)
142    Instant,
143    /// Big integer type (BigInt)
144    BigInteger,
145    /// Big decimal type (BigDecimal)
146    BigDecimal,
147}
148
149impl DataType {
150    /// Get the string representation of the data type
151    ///
152    /// # Returns
153    ///
154    /// Returns the name string of the data type
155    ///
156    /// # Examples
157    ///
158    /// ```rust,ignore
159    /// use qubit_common::lang::DataType;
160    ///
161    /// assert_eq!(DataType::Int32.as_str(), "int32");
162    /// assert_eq!(DataType::String.as_str(), "string");
163    /// ```
164    pub const fn as_str(&self) -> &'static str {
165        match self {
166            DataType::Bool => "bool",
167            DataType::Char => "char",
168            DataType::Int8 => "int8",
169            DataType::Int16 => "int16",
170            DataType::Int32 => "int32",
171            DataType::Int64 => "int64",
172            DataType::Int128 => "int128",
173            DataType::UInt8 => "uint8",
174            DataType::UInt16 => "uint16",
175            DataType::UInt32 => "uint32",
176            DataType::UInt64 => "uint64",
177            DataType::UInt128 => "uint128",
178            DataType::Float32 => "float32",
179            DataType::Float64 => "float64",
180            DataType::String => "string",
181            DataType::Date => "date",
182            DataType::Time => "time",
183            DataType::DateTime => "datetime",
184            DataType::Instant => "instant",
185            DataType::BigInteger => "biginteger",
186            DataType::BigDecimal => "bigdecimal",
187        }
188    }
189}
190
191impl std::fmt::Display for DataType {
192    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193        write!(f, "{}", self.as_str())
194    }
195}
196
197// =============================================================================
198// Compile-time mapping from types to DataType
199// =============================================================================
200
201/// Marker trait for mapping concrete Rust types to `DataType`
202///
203/// Provides an associated constant to know the corresponding `DataType` at compile time,
204/// facilitating static type-to-data-type queries in generic code based on `T`.
205///
206/// This trait enables compile-time type-to-data-type mapping, allowing generic code
207/// to determine the appropriate `DataType` for any type that implements this trait.
208/// This is particularly useful for serialization frameworks, validation systems,
209/// and other scenarios where you need to know the data type at compile time.
210///
211/// # Usage
212///
213/// The trait is automatically implemented for all basic Rust types and common
214/// third-party types. You can use it in generic functions to determine the
215/// corresponding `DataType` for any type.
216///
217/// # Examples
218///
219/// ## Basic Usage
220///
221/// ```rust,ignore
222/// use qubit_common::lang::{DataType, DataTypeOf};
223///
224/// // Get the data type for a specific type
225/// assert_eq!(i32::DATA_TYPE, DataType::Int32);
226/// assert_eq!(String::DATA_TYPE, DataType::String);
227/// assert_eq!(bool::DATA_TYPE, DataType::Bool);
228/// ```
229///
230/// ## Generic Function Example
231///
232/// ```rust,ignore
233/// use qubit_common::lang::{DataType, DataTypeOf};
234///
235/// fn get_type_name<T: DataTypeOf>() -> &'static str {
236///     T::DATA_TYPE.as_str()
237/// }
238///
239/// assert_eq!(get_type_name::<i32>(), "int32");
240/// assert_eq!(get_type_name::<String>(), "string");
241/// assert_eq!(get_type_name::<f64>(), "float64");
242/// ```
243///
244/// ## Generic Value Container Example
245///
246/// ```rust,ignore
247/// use qubit_common::lang::{DataType, DataTypeOf};
248///
249/// struct TypedValue<T: DataTypeOf> {
250///     value: T,
251///     data_type: DataType,
252/// }
253///
254/// impl<T: DataTypeOf> TypedValue<T> {
255///     fn new(value: T) -> Self {
256///         Self {
257///             value,
258///             data_type: T::DATA_TYPE,
259///         }
260///     }
261///
262///     fn get_data_type(&self) -> DataType {
263///         self.data_type
264///     }
265/// }
266///
267/// let typed_value = TypedValue::new(42i32);
268/// assert_eq!(typed_value.get_data_type(), DataType::Int32);
269/// ```
270///
271/// ## Type Validation Example
272///
273/// ```rust,ignore
274/// use qubit_common::lang::{DataType, DataTypeOf};
275///
276/// fn validate_numeric_type<T: DataTypeOf>() -> bool {
277///     matches!(T::DATA_TYPE,
278///         DataType::Int8 | DataType::Int16 | DataType::Int32 | DataType::Int64 | DataType::Int128 |
279///         DataType::UInt8 | DataType::UInt16 | DataType::UInt32 | DataType::UInt64 | DataType::UInt128 |
280///         DataType::Float32 | DataType::Float64 | DataType::BigInteger | DataType::BigDecimal
281///     )
282/// }
283///
284/// assert!(validate_numeric_type::<i32>());
285/// assert!(validate_numeric_type::<f64>());
286/// assert!(!validate_numeric_type::<String>());
287/// ```
288///
289/// # Supported Types
290///
291/// The following types have `DataTypeOf` implementations:
292///
293/// - **Basic Types**: `bool`, `char`, `i8`, `i16`, `i32`, `i64`, `i128`, `u8`, `u16`, `u32`, `u64`, `u128`, `f32`, `f64`
294/// - **String Types**: `String`
295/// - **Date/Time Types**: `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
296/// - **Big Number Types**: `BigInt`, `BigDecimal`
297///
298/// # Author
299///
300/// Haixing Hu
301///
302pub trait DataTypeOf {
303    /// The `DataType` corresponding to this Rust type
304    const DATA_TYPE: DataType;
305}
306
307// Basic scalar types
308impl DataTypeOf for bool {
309    const DATA_TYPE: DataType = DataType::Bool;
310}
311impl DataTypeOf for char {
312    const DATA_TYPE: DataType = DataType::Char;
313}
314impl DataTypeOf for i8 {
315    const DATA_TYPE: DataType = DataType::Int8;
316}
317impl DataTypeOf for i16 {
318    const DATA_TYPE: DataType = DataType::Int16;
319}
320impl DataTypeOf for i32 {
321    const DATA_TYPE: DataType = DataType::Int32;
322}
323impl DataTypeOf for i64 {
324    const DATA_TYPE: DataType = DataType::Int64;
325}
326impl DataTypeOf for i128 {
327    const DATA_TYPE: DataType = DataType::Int128;
328}
329impl DataTypeOf for u8 {
330    const DATA_TYPE: DataType = DataType::UInt8;
331}
332impl DataTypeOf for u16 {
333    const DATA_TYPE: DataType = DataType::UInt16;
334}
335impl DataTypeOf for u32 {
336    const DATA_TYPE: DataType = DataType::UInt32;
337}
338impl DataTypeOf for u64 {
339    const DATA_TYPE: DataType = DataType::UInt64;
340}
341impl DataTypeOf for u128 {
342    const DATA_TYPE: DataType = DataType::UInt128;
343}
344impl DataTypeOf for f32 {
345    const DATA_TYPE: DataType = DataType::Float32;
346}
347impl DataTypeOf for f64 {
348    const DATA_TYPE: DataType = DataType::Float64;
349}
350
351// String types
352impl DataTypeOf for String {
353    const DATA_TYPE: DataType = DataType::String;
354}
355
356// Date and time types (chrono)
357impl DataTypeOf for NaiveDate {
358    const DATA_TYPE: DataType = DataType::Date;
359}
360impl DataTypeOf for NaiveTime {
361    const DATA_TYPE: DataType = DataType::Time;
362}
363impl DataTypeOf for NaiveDateTime {
364    const DATA_TYPE: DataType = DataType::DateTime;
365}
366impl DataTypeOf for DateTime<Utc> {
367    const DATA_TYPE: DataType = DataType::Instant;
368}
369
370// Big number types
371impl DataTypeOf for BigInt {
372    const DATA_TYPE: DataType = DataType::BigInteger;
373}
374impl DataTypeOf for BigDecimal {
375    const DATA_TYPE: DataType = DataType::BigDecimal;
376}