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