xdl_core/
lib.rs

1//! # XDL Core
2//!
3//! Core data structures and types for the Extended Data Language (XDL) Rust implementation.
4//! This module provides the fundamental building blocks for XDL data types and operations.
5
6pub mod array;
7pub mod dimension;
8pub mod error;
9pub mod types;
10
11use serde::{Deserialize, Serialize};
12use std::fmt;
13
14pub use array::*;
15pub use dimension::*;
16pub use error::*;
17pub use types::*;
18
19/// Maximum number of dimensions supported by XDL arrays
20pub const MAXRANK: usize = 8;
21
22/// XDL data types enumeration
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
24pub enum GdlType {
25    Undefined,
26    Byte,
27    Int,
28    Long,
29    Float,
30    Double,
31    Complex,
32    DComplex,
33    String,
34    Struct,
35    Pointer,
36    ObjRef,
37    UInt,
38    ULong,
39    Long64,
40    ULong64,
41}
42
43impl GdlType {
44    /// Returns the size in bytes of this type
45    pub fn size(self) -> usize {
46        match self {
47            GdlType::Undefined => 0,
48            GdlType::Byte => 1,
49            GdlType::Int => 2,
50            GdlType::Long => 4,
51            GdlType::Float => 4,
52            GdlType::Double => 8,
53            GdlType::Complex => 8,
54            GdlType::DComplex => 16,
55            GdlType::String => std::mem::size_of::<String>(),
56            GdlType::Struct => 0, // Variable size
57            GdlType::Pointer => std::mem::size_of::<usize>(),
58            GdlType::ObjRef => std::mem::size_of::<usize>(),
59            GdlType::UInt => 2,
60            GdlType::ULong => 4,
61            GdlType::Long64 => 8,
62            GdlType::ULong64 => 8,
63        }
64    }
65
66    /// Returns true if this is a numeric type
67    pub fn is_numeric(self) -> bool {
68        matches!(
69            self,
70            GdlType::Byte
71                | GdlType::Int
72                | GdlType::Long
73                | GdlType::Float
74                | GdlType::Double
75                | GdlType::Complex
76                | GdlType::DComplex
77                | GdlType::UInt
78                | GdlType::ULong
79                | GdlType::Long64
80                | GdlType::ULong64
81        )
82    }
83
84    /// Returns true if this is an integer type
85    pub fn is_integer(self) -> bool {
86        matches!(
87            self,
88            GdlType::Byte
89                | GdlType::Int
90                | GdlType::Long
91                | GdlType::UInt
92                | GdlType::ULong
93                | GdlType::Long64
94                | GdlType::ULong64
95        )
96    }
97
98    /// Returns true if this is a floating point type
99    pub fn is_float(self) -> bool {
100        matches!(self, GdlType::Float | GdlType::Double)
101    }
102
103    /// Returns true if this is a complex type
104    pub fn is_complex(self) -> bool {
105        matches!(self, GdlType::Complex | GdlType::DComplex)
106    }
107}
108
109impl fmt::Display for GdlType {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        let name = match self {
112            GdlType::Undefined => "UNDEFINED",
113            GdlType::Byte => "BYTE",
114            GdlType::Int => "INT",
115            GdlType::Long => "LONG",
116            GdlType::Float => "FLOAT",
117            GdlType::Double => "DOUBLE",
118            GdlType::Complex => "COMPLEX",
119            GdlType::DComplex => "DCOMPLEX",
120            GdlType::String => "STRING",
121            GdlType::Struct => "STRUCT",
122            GdlType::Pointer => "POINTER",
123            GdlType::ObjRef => "OBJREF",
124            GdlType::UInt => "UINT",
125            GdlType::ULong => "ULONG",
126            GdlType::Long64 => "LONG64",
127            GdlType::ULong64 => "ULONG64",
128        };
129        write!(f, "{}", name)
130    }
131}
132
133#[cfg(test)]
134mod tests {
135    use super::*;
136
137    #[test]
138    fn test_gdl_type_sizes() {
139        assert_eq!(GdlType::Byte.size(), 1);
140        assert_eq!(GdlType::Int.size(), 2);
141        assert_eq!(GdlType::Long.size(), 4);
142        assert_eq!(GdlType::Float.size(), 4);
143        assert_eq!(GdlType::Double.size(), 8);
144        assert_eq!(GdlType::Complex.size(), 8);
145        assert_eq!(GdlType::DComplex.size(), 16);
146    }
147
148    #[test]
149    fn test_type_predicates() {
150        assert!(GdlType::Float.is_numeric());
151        assert!(GdlType::Int.is_integer());
152        assert!(GdlType::Float.is_float());
153        assert!(GdlType::Complex.is_complex());
154        assert!(!GdlType::String.is_numeric());
155    }
156}