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