1use polars_dtype::categorical::CategoricalPhysical;
8use serde::{Deserialize, Serialize};
9
10use super::*;
11
12impl<'a> Deserialize<'a> for DataType {
13 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
14 where
15 D: Deserializer<'a>,
16 {
17 Ok(SerializableDataType::deserialize(deserializer)?.into())
18 }
19}
20
21impl Serialize for DataType {
22 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
23 where
24 S: Serializer,
25 {
26 let dt: SerializableDataType = self.into();
27 dt.serialize(serializer)
28 }
29}
30
31#[cfg(feature = "dsl-schema")]
32impl schemars::JsonSchema for DataType {
33 fn schema_name() -> std::borrow::Cow<'static, str> {
34 SerializableDataType::schema_name()
35 }
36
37 fn schema_id() -> std::borrow::Cow<'static, str> {
38 SerializableDataType::schema_id()
39 }
40
41 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
42 SerializableDataType::json_schema(generator)
43 }
44}
45
46#[derive(Serialize, Deserialize)]
47#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]
48#[serde(rename = "DataType")]
49enum SerializableDataType {
50 Boolean,
51 UInt8,
52 UInt16,
53 UInt32,
54 UInt64,
55 UInt128,
56 Int8,
57 Int16,
58 Int32,
59 Int64,
60 Int128,
61 Float32,
62 Float64,
63 String,
64 Binary,
65 BinaryOffset,
66 Date,
69 Datetime(TimeUnit, Option<TimeZone>),
72 Duration(TimeUnit),
74 Time,
76 List(Box<SerializableDataType>),
77 #[cfg(feature = "dtype-array")]
78 Array(Box<SerializableDataType>, usize),
79 Null,
80 #[cfg(feature = "dtype-struct")]
81 Struct(Vec<Field>),
82 Unknown(UnknownKind),
84 #[cfg(feature = "dtype-categorical")]
85 Categorical {
86 name: String,
87 namespace: String,
88 physical: CategoricalPhysical,
89 },
90 #[cfg(feature = "dtype-categorical")]
91 Enum {
92 strings: Series,
93 },
94 #[cfg(feature = "dtype-decimal")]
95 Decimal(usize, usize),
96 #[cfg(feature = "object")]
97 Object(String),
98}
99
100impl From<&DataType> for SerializableDataType {
101 fn from(dt: &DataType) -> Self {
102 use DataType::*;
103 match dt {
104 Boolean => Self::Boolean,
105 UInt8 => Self::UInt8,
106 UInt16 => Self::UInt16,
107 UInt32 => Self::UInt32,
108 UInt64 => Self::UInt64,
109 UInt128 => Self::UInt128,
110 Int8 => Self::Int8,
111 Int16 => Self::Int16,
112 Int32 => Self::Int32,
113 Int64 => Self::Int64,
114 Int128 => Self::Int128,
115 Float32 => Self::Float32,
116 Float64 => Self::Float64,
117 String => Self::String,
118 Binary => Self::Binary,
119 BinaryOffset => Self::BinaryOffset,
120 Date => Self::Date,
121 Datetime(tu, tz) => Self::Datetime(*tu, tz.clone()),
122 Duration(tu) => Self::Duration(*tu),
123 Time => Self::Time,
124 List(dt) => Self::List(Box::new(dt.as_ref().into())),
125 #[cfg(feature = "dtype-array")]
126 Array(dt, width) => Self::Array(Box::new(dt.as_ref().into()), *width),
127 Null => Self::Null,
128 Unknown(kind) => Self::Unknown(*kind),
129 #[cfg(feature = "dtype-struct")]
130 Struct(flds) => Self::Struct(flds.clone()),
131 #[cfg(feature = "dtype-categorical")]
132 Categorical(cats, _) => Self::Categorical {
133 name: cats.name().to_string(),
134 namespace: cats.namespace().to_string(),
135 physical: cats.physical(),
136 },
137 #[cfg(feature = "dtype-categorical")]
138 Enum(fcats, _) => Self::Enum {
139 strings: StringChunked::with_chunk(
140 PlSmallStr::from_static("categories"),
141 fcats.categories().clone(),
142 )
143 .into_series(),
144 },
145 #[cfg(feature = "dtype-decimal")]
146 Decimal(precision, scale) => Self::Decimal(*precision, *scale),
147 #[cfg(feature = "object")]
148 Object(name) => Self::Object(name.to_string()),
149 }
150 }
151}
152impl From<SerializableDataType> for DataType {
153 fn from(dt: SerializableDataType) -> Self {
154 use SerializableDataType::*;
155 match dt {
156 Boolean => Self::Boolean,
157 UInt8 => Self::UInt8,
158 UInt16 => Self::UInt16,
159 UInt32 => Self::UInt32,
160 UInt64 => Self::UInt64,
161 UInt128 => Self::UInt128,
162 Int8 => Self::Int8,
163 Int16 => Self::Int16,
164 Int32 => Self::Int32,
165 Int64 => Self::Int64,
166 Int128 => Self::Int128,
167 Float32 => Self::Float32,
168 Float64 => Self::Float64,
169 String => Self::String,
170 Binary => Self::Binary,
171 BinaryOffset => Self::BinaryOffset,
172 Date => Self::Date,
173 Datetime(tu, tz) => Self::Datetime(tu, tz),
174 Duration(tu) => Self::Duration(tu),
175 Time => Self::Time,
176 List(dt) => Self::List(Box::new((*dt).into())),
177 #[cfg(feature = "dtype-array")]
178 Array(dt, width) => Self::Array(Box::new((*dt).into()), width),
179 Null => Self::Null,
180 Unknown(kind) => Self::Unknown(kind),
181 #[cfg(feature = "dtype-struct")]
182 Struct(flds) => Self::Struct(flds),
183 #[cfg(feature = "dtype-categorical")]
184 Categorical {
185 name,
186 namespace,
187 physical,
188 } => {
189 let cats = Categories::new(
190 PlSmallStr::from(name),
191 PlSmallStr::from(namespace),
192 physical,
193 );
194 let mapping = cats.mapping();
195 Self::Categorical(cats, mapping)
196 },
197 #[cfg(feature = "dtype-categorical")]
198 Enum { strings } => {
199 let ca = strings.str().unwrap();
200 let fcats = FrozenCategories::new(ca.iter().flatten()).unwrap();
201 let mapping = fcats.mapping().clone();
202 Self::Enum(fcats, mapping)
203 },
204 #[cfg(feature = "dtype-decimal")]
205 Decimal(precision, scale) => Self::Decimal(precision, scale),
206 #[cfg(feature = "object")]
207 Object(_) => Self::Object("unknown"),
208 }
209 }
210}