1use serde::ser::Serializer;
14use serde::{Deserialize, Serialize};
15
16macro_rules! wire_newtype {
20 ($(#[$doc:meta])* $name:ident($inner:ty)) => {
21 $(#[$doc])*
22 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
23 pub struct $name(pub $inner);
24
25 impl Serialize for $name {
26 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
27 serializer.serialize_newtype_struct(stringify!($name), &self.0)
28 }
29 }
30
31 impl<'de> Deserialize<'de> for $name {
32 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
33 <$inner as Deserialize<'de>>::deserialize(d).map($name)
34 }
35 }
36 };
37}
38
39wire_newtype! {
40 DateDays(u16)
43}
44
45wire_newtype! {
46 Date32Days(i32)
50}
51
52wire_newtype! {
53 DateTimeSeconds(u32)
56}
57
58wire_newtype! {
59 DateTime64Secs(i64)
62}
63
64wire_newtype! {
65 DateTime64Millis(i64)
68}
69
70wire_newtype! {
71 DateTime64Micros(i64)
74}
75
76wire_newtype! {
77 DateTime64Nanos(i64)
80}
81
82wire_newtype! {
83 TimeSeconds(i32)
86}
87
88wire_newtype! {
89 Time64Secs(i64)
92}
93
94wire_newtype! {
95 Time64Millis(i64)
98}
99
100wire_newtype! {
101 Time64Micros(i64)
104}
105
106wire_newtype! {
107 Time64Nanos(i64)
110}
111
112macro_rules! decimal_newtype {
119 ($(#[$doc:meta])* $name:ident($inner:ty), max_scale = $max:literal) => {
120 $(#[$doc])*
121 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
122 pub struct $name<const SCALE: u32>(pub $inner);
123
124 impl<const SCALE: u32> $name<SCALE> {
125 pub const SCALE: u32 = {
128 assert!(
129 SCALE <= $max,
130 concat!(
131 stringify!($name),
132 " scale exceeds the column type's maximum of ",
133 stringify!($max)
134 )
135 );
136 SCALE
137 };
138 }
139
140 impl<const SCALE: u32> Serialize for $name<SCALE> {
141 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
142 let _ = Self::SCALE;
145 serializer.serialize_newtype_struct(stringify!($name), &self.0)
146 }
147 }
148
149 impl<'de, const SCALE: u32> Deserialize<'de> for $name<SCALE> {
150 fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
151 let _ = Self::SCALE;
152 <$inner as Deserialize<'de>>::deserialize(d).map($name)
153 }
154 }
155 };
156}
157
158decimal_newtype! {
159 Decimal32(i32), max_scale = 9
162}
163
164decimal_newtype! {
165 Decimal64(i64), max_scale = 18
168}
169
170decimal_newtype! {
171 Decimal128(i128), max_scale = 38
174}
175
176#[cfg(feature = "rust_decimal")]
179#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
180#[non_exhaustive]
181pub enum DecimalConvertError {
182 #[error("{value} cannot be rescaled to {scale} fractional digits")]
187 Rescale {
188 value: rust_decimal::Decimal,
190 scale: u32,
192 },
193 #[error("scaled mantissa of {value} overflows the column's integer width")]
195 Overflow {
196 value: rust_decimal::Decimal,
198 },
199 #[error("raw decimal {raw} at scale {scale} exceeds rust_decimal's range")]
202 Unrepresentable {
203 raw: i128,
205 scale: u32,
207 },
208}
209
210#[cfg(feature = "rust_decimal")]
217mod rust_decimal_conv {
218 use super::{Decimal32, Decimal64, Decimal128, DecimalConvertError};
219 use rust_decimal::Decimal;
220
221 macro_rules! decimal_conversions {
222 ($wrapper:ident, $int:ty) => {
223 impl<const SCALE: u32> TryFrom<Decimal> for $wrapper<SCALE> {
224 type Error = DecimalConvertError;
225
226 fn try_from(value: Decimal) -> Result<Self, Self::Error> {
227 let _ = Self::SCALE;
229 let mut scaled = value;
230 scaled.rescale(SCALE);
231 if scaled.scale() != SCALE {
232 return Err(DecimalConvertError::Rescale {
235 value,
236 scale: SCALE,
237 });
238 }
239 <$int>::try_from(scaled.mantissa())
240 .map($wrapper)
241 .map_err(|_| DecimalConvertError::Overflow { value })
242 }
243 }
244
245 impl<const SCALE: u32> TryFrom<$wrapper<SCALE>> for Decimal {
246 type Error = DecimalConvertError;
247
248 fn try_from(value: $wrapper<SCALE>) -> Result<Self, Self::Error> {
249 Decimal::try_from_i128_with_scale(i128::from(value.0), SCALE).map_err(|_| {
250 DecimalConvertError::Unrepresentable {
251 raw: i128::from(value.0),
252 scale: SCALE,
253 }
254 })
255 }
256 }
257 };
258 }
259
260 decimal_conversions!(Decimal32, i32);
261 decimal_conversions!(Decimal64, i64);
262 decimal_conversions!(Decimal128, i128);
263}
264
265#[derive(Clone, Copy, Debug, PartialEq, Eq)]
272pub struct Int256(pub [u8; 32]);
273
274impl Int256 {
275 #[must_use]
277 pub const fn from_i128(v: i128) -> Self {
278 let mut bytes = [if v < 0 { 0xff } else { 0x00 }; 32];
279 let le = v.to_le_bytes();
280 let mut i = 0;
281 while i < 16 {
282 bytes[i] = le[i];
283 i += 1;
284 }
285 Int256(bytes)
286 }
287
288 #[must_use]
290 pub const fn from_le_bytes(bytes: [u8; 32]) -> Self {
291 Int256(bytes)
292 }
293
294 #[must_use]
296 pub const fn to_le_bytes(self) -> [u8; 32] {
297 self.0
298 }
299}
300
301impl Serialize for Int256 {
302 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
303 serializer.serialize_newtype_struct("Int256", &self.0)
306 }
307}
308
309impl<'de> Deserialize<'de> for Int256 {
310 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
311 <[u8; 32]>::deserialize(d).map(Int256)
312 }
313}
314
315#[derive(Clone, Copy, Debug, PartialEq, Eq)]
319pub struct UInt256(pub [u8; 32]);
320
321impl UInt256 {
322 #[must_use]
324 pub const fn from_u128(v: u128) -> Self {
325 let mut bytes = [0u8; 32];
326 let le = v.to_le_bytes();
327 let mut i = 0;
328 while i < 16 {
329 bytes[i] = le[i];
330 i += 1;
331 }
332 UInt256(bytes)
333 }
334
335 #[must_use]
337 pub const fn from_le_bytes(bytes: [u8; 32]) -> Self {
338 UInt256(bytes)
339 }
340
341 #[must_use]
343 pub const fn to_le_bytes(self) -> [u8; 32] {
344 self.0
345 }
346}
347
348impl Serialize for UInt256 {
349 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
350 serializer.serialize_newtype_struct("UInt256", &self.0)
351 }
352}
353
354impl<'de> Deserialize<'de> for UInt256 {
355 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
356 <[u8; 32]>::deserialize(d).map(UInt256)
357 }
358}
359
360pub type Point = (f64, f64);
362pub type Ring = Vec<Point>;
364pub type LineString = Vec<Point>;
366pub type Polygon = Vec<Ring>;
368pub type MultiLineString = Vec<LineString>;
370pub type MultiPolygon = Vec<Polygon>;
372
373#[cfg(test)]
374mod tests {
375 use super::*;
376 use crate::rowbinary::serialize_row;
377 use bytes::BytesMut;
378
379 fn enc<T: Serialize>(v: &T) -> Vec<u8> {
380 let mut buf = BytesMut::new();
381 serialize_row(v, &mut buf).expect("serialize");
382 buf.to_vec()
383 }
384
385 #[test]
386 fn date_and_time_newtypes_are_transparent_integers() {
387 assert_eq!(enc(&DateDays(1)), 1u16.to_le_bytes());
388 assert_eq!(enc(&Date32Days(-25567)), (-25567i32).to_le_bytes());
389 assert_eq!(enc(&DateTimeSeconds(42)), 42u32.to_le_bytes());
390 assert_eq!(enc(&DateTime64Secs(-1)), (-1i64).to_le_bytes());
391 assert_eq!(enc(&DateTime64Millis(1_000)), 1_000i64.to_le_bytes());
392 assert_eq!(enc(&DateTime64Micros(7)), 7i64.to_le_bytes());
393 assert_eq!(enc(&DateTime64Nanos(7)), 7i64.to_le_bytes());
394 assert_eq!(enc(&TimeSeconds(-3599)), (-3599i32).to_le_bytes());
395 assert_eq!(enc(&Time64Nanos(1)), 1i64.to_le_bytes());
396 }
397
398 #[test]
399 fn decimals_write_the_raw_scaled_integer() {
400 assert_eq!(enc(&Decimal32::<2>(999)), 999i32.to_le_bytes());
401 assert_eq!(enc(&Decimal64::<4>(-15_000)), (-15_000i64).to_le_bytes());
402 assert_eq!(enc(&Decimal128::<10>(1)), 1i128.to_le_bytes());
403 }
407
408 #[test]
409 fn int256_layouts() {
410 assert_eq!(Int256::from_i128(-1).0, [0xff; 32]);
411 let one = UInt256::from_u128(1);
412 let mut expected = [0u8; 32];
413 expected[0] = 1;
414 assert_eq!(one.0, expected);
415
416 let v = Int256::from_i128(i128::MIN);
418 assert_eq!(&v.0[..16], &i128::MIN.to_le_bytes());
419 assert_eq!(&v.0[16..], &[0xff; 16]);
420
421 assert_eq!(enc(&one), expected);
423 assert_eq!(enc(&Int256::from_i128(-1)), [0xff; 32]);
424 }
425
426 #[cfg(feature = "rust_decimal")]
427 #[test]
428 fn rust_decimal_conversions_are_checked_and_round_trip() {
429 use rust_decimal::Decimal;
430
431 let d = Decimal::new(1505, 3);
434 assert_eq!(Decimal64::<2>::try_from(d), Ok(Decimal64::<2>(151)));
435
436 let wrapped = Decimal64::<4>::try_from(Decimal::new(-15_000, 4)).unwrap();
438 assert_eq!(wrapped, Decimal64::<4>(-15_000));
439 assert_eq!(
440 Decimal::try_from(wrapped).unwrap(),
441 Decimal::new(-15_000, 4)
442 );
443
444 assert!(matches!(
446 Decimal32::<0>::try_from(Decimal::MAX),
447 Err(DecimalConvertError::Overflow { .. })
448 ));
449
450 assert!(matches!(
452 Decimal128::<10>::try_from(Decimal::MAX),
453 Err(DecimalConvertError::Rescale { scale: 10, .. })
454 ));
455
456 assert!(matches!(
459 Decimal::try_from(Decimal128::<2>(i128::MAX)),
460 Err(DecimalConvertError::Unrepresentable { .. })
461 ));
462 }
463
464 #[test]
465 fn geo_shapes_encode_as_nested_arrays_of_points() {
466 let p: Point = (1.0, 2.0);
467 let mut expected = 1.0f64.to_le_bytes().to_vec();
468 expected.extend_from_slice(&2.0f64.to_le_bytes());
469 assert_eq!(enc(&p), expected);
470
471 let ring: Ring = vec![(1.0, 2.0), (3.0, 4.0)];
472 let bytes = enc(&ring);
473 assert_eq!(bytes[0], 2, "LEB128 point count");
474 assert_eq!(bytes.len(), 1 + 2 * 16);
475
476 let poly: Polygon = vec![ring.clone()];
477 let bytes = enc(&poly);
478 assert_eq!(bytes[0], 1, "one ring");
479 assert_eq!(bytes[1], 2, "two points");
480
481 let multi: MultiPolygon = vec![poly];
482 assert_eq!(enc(&multi)[0], 1);
483 }
484}