Skip to main content

tdb_succinct/tfc/
datatypes.rs

1use super::{
2    datetime::{datetime_to_storage, storage_to_datetime},
3    decimal::{decimal_to_storage, storage_to_decimal, Decimal},
4    integer::{bigint_to_storage, storage_to_bigint},
5    TypedDictEntry,
6};
7use base64::display::Base64Display;
8use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
9use bytes::{Buf, BufMut, Bytes, BytesMut};
10use chrono::{NaiveDateTime, NaiveTime};
11use num_derive::FromPrimitive;
12use rug::Integer;
13
14#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, FromPrimitive, Hash)]
15pub enum Datatype {
16    String = 0,
17    UInt32,
18    Int32,
19    Float32,
20    UInt64,
21    Int64,
22    Float64,
23    Decimal,
24    BigInt,
25    Boolean,
26    LangString,
27    AnyURI,
28    Language,
29    NormalizedString,
30    Token,
31    NMToken,
32    Name,
33    NCName,
34    Notation,
35    QName,
36    ID,
37    IDRef,
38    Entity,
39    PositiveInteger,
40    NonNegativeInteger,
41    NonPositiveInteger,
42    NegativeInteger,
43    Date,
44    DateTime,
45    DateTimeStamp,
46    Time,
47    GYear,
48    GMonth,
49    GDay,
50    GYearMonth,
51    GMonthDay,
52    Duration,
53    YearMonthDuration,
54    DayTimeDuration,
55    UInt8,
56    Int8,
57    UInt16,
58    Int16,
59    Base64Binary,
60    HexBinary,
61    AnySimpleType,
62}
63
64impl Datatype {
65    pub fn cast<T: TdbDataType, B: Buf>(self, b: B) -> T {
66        if T::datatype() != self {
67            panic!("not the right datatype");
68        }
69
70        T::from_lexical(b)
71    }
72
73    pub fn record_size(&self) -> Option<u8> {
74        match self {
75            Datatype::Boolean => None,
76            Datatype::String => None,
77            Datatype::UInt32 => Some(4),
78            Datatype::Int32 => Some(4),
79            Datatype::UInt64 => Some(8),
80            Datatype::Int64 => Some(8),
81            Datatype::Float32 => Some(4),
82            Datatype::Float64 => Some(8),
83            Datatype::Decimal => None,
84            Datatype::BigInt => None,
85            Datatype::Token => None,
86            Datatype::LangString => None,
87            _ => None,
88        }
89    }
90}
91
92pub trait TdbDataType: FromLexical<Self> + ToLexical<Self> {
93    fn datatype() -> Datatype;
94
95    fn make_entry<T>(val: &T) -> TypedDictEntry
96    where
97        T: ToLexical<Self> + ?Sized,
98    {
99        TypedDictEntry::new(Self::datatype(), val.to_lexical().into())
100    }
101}
102
103pub trait ToLexical<T: ?Sized> {
104    fn to_lexical(&self) -> Bytes;
105}
106
107pub trait FromLexical<T: ?Sized> {
108    fn from_lexical<B: Buf>(b: B) -> Self;
109}
110
111impl<T: AsRef<str>> ToLexical<String> for T {
112    fn to_lexical(&self) -> Bytes {
113        Bytes::copy_from_slice(self.as_ref().as_bytes())
114    }
115}
116
117impl FromLexical<String> for String {
118    fn from_lexical<B: Buf>(mut b: B) -> Self {
119        let mut vec = vec![0; b.remaining()];
120        b.copy_to_slice(&mut vec);
121        String::from_utf8(vec).unwrap()
122    }
123}
124
125impl TdbDataType for String {
126    fn datatype() -> Datatype {
127        Datatype::String
128    }
129}
130
131impl TdbDataType for u8 {
132    fn datatype() -> Datatype {
133        Datatype::UInt8
134    }
135}
136
137impl FromLexical<u8> for u8 {
138    fn from_lexical<B: Buf>(b: B) -> Self {
139        b.reader().read_u8().unwrap()
140    }
141}
142
143impl ToLexical<u8> for u8 {
144    fn to_lexical(&self) -> Bytes {
145        let mut buf = BytesMut::new().writer();
146        buf.write_u8(*self).unwrap();
147
148        buf.into_inner().freeze()
149    }
150}
151
152impl TdbDataType for u16 {
153    fn datatype() -> Datatype {
154        Datatype::UInt16
155    }
156}
157
158impl FromLexical<u16> for u16 {
159    fn from_lexical<B: Buf>(b: B) -> Self {
160        b.reader().read_u16::<BigEndian>().unwrap()
161    }
162}
163
164impl ToLexical<u16> for u16 {
165    fn to_lexical(&self) -> Bytes {
166        let mut buf = BytesMut::new().writer();
167        buf.write_u16::<BigEndian>(*self).unwrap();
168
169        buf.into_inner().freeze()
170    }
171}
172
173impl TdbDataType for u32 {
174    fn datatype() -> Datatype {
175        Datatype::UInt32
176    }
177}
178
179impl FromLexical<u16> for u32 {
180    fn from_lexical<B: Buf>(b: B) -> Self {
181        b.reader().read_u16::<BigEndian>().unwrap() as u32
182    }
183}
184
185impl FromLexical<u32> for u32 {
186    fn from_lexical<B: Buf>(b: B) -> Self {
187        b.reader().read_u32::<BigEndian>().unwrap()
188    }
189}
190
191impl ToLexical<u32> for u32 {
192    fn to_lexical(&self) -> Bytes {
193        let mut buf = BytesMut::new().writer();
194        buf.write_u32::<BigEndian>(*self).unwrap();
195
196        buf.into_inner().freeze()
197    }
198}
199
200const I8_BYTE_MASK: u8 = 0b1000_0000;
201impl TdbDataType for i8 {
202    fn datatype() -> Datatype {
203        Datatype::Int8
204    }
205}
206
207impl FromLexical<i8> for i8 {
208    fn from_lexical<B: Buf>(b: B) -> Self {
209        let i = b.reader().read_u8().unwrap();
210        (I8_BYTE_MASK ^ i) as i8
211    }
212}
213
214impl ToLexical<i8> for i8 {
215    fn to_lexical(&self) -> Bytes {
216        let sign_flip = I8_BYTE_MASK ^ (*self as u8);
217        let mut buf = BytesMut::new().writer();
218        buf.write_u8(sign_flip).unwrap();
219        buf.into_inner().freeze()
220    }
221}
222
223const I16_BYTE_MASK: u16 = 0b1000_0000 << 8;
224impl TdbDataType for i16 {
225    fn datatype() -> Datatype {
226        Datatype::Int16
227    }
228}
229
230impl FromLexical<i16> for i16 {
231    fn from_lexical<B: Buf>(b: B) -> Self {
232        let i = b.reader().read_u16::<BigEndian>().unwrap();
233        (I16_BYTE_MASK ^ i) as i16
234    }
235}
236
237impl ToLexical<i16> for i16 {
238    fn to_lexical(&self) -> Bytes {
239        let sign_flip = I16_BYTE_MASK ^ (*self as u16);
240        let mut buf = BytesMut::new().writer();
241        buf.write_u16::<BigEndian>(sign_flip).unwrap();
242        buf.into_inner().freeze()
243    }
244}
245
246const I32_BYTE_MASK: u32 = 0b1000_0000 << (3 * 8);
247impl TdbDataType for i32 {
248    fn datatype() -> Datatype {
249        Datatype::Int32
250    }
251}
252
253impl FromLexical<i16> for i32 {
254    fn from_lexical<B: Buf>(b: B) -> Self {
255        b.reader().read_i16::<BigEndian>().unwrap() as i32
256    }
257}
258
259impl FromLexical<u16> for i32 {
260    fn from_lexical<B: Buf>(b: B) -> Self {
261        b.reader().read_u16::<BigEndian>().unwrap() as i32
262    }
263}
264
265impl FromLexical<i32> for i32 {
266    fn from_lexical<B: Buf>(b: B) -> Self {
267        let i = b.reader().read_u32::<BigEndian>().unwrap();
268        (I32_BYTE_MASK ^ i) as i32
269    }
270}
271
272impl ToLexical<u8> for i32 {
273    fn to_lexical(&self) -> Bytes {
274        <i32 as ToLexical<i32>>::to_lexical(&self as &i32)
275    }
276}
277
278impl ToLexical<u16> for i32 {
279    fn to_lexical(&self) -> Bytes {
280        <i32 as ToLexical<i32>>::to_lexical(&self as &i32)
281    }
282}
283
284impl ToLexical<i8> for i32 {
285    fn to_lexical(&self) -> Bytes {
286        <i32 as ToLexical<i32>>::to_lexical(&self as &i32)
287    }
288}
289
290impl ToLexical<i16> for i32 {
291    fn to_lexical(&self) -> Bytes {
292        <i32 as ToLexical<i32>>::to_lexical(&self as &i32)
293    }
294}
295
296impl ToLexical<i32> for i32 {
297    fn to_lexical(&self) -> Bytes {
298        let sign_flip = I32_BYTE_MASK ^ (*self as u32);
299        let mut buf = BytesMut::new().writer();
300        buf.write_u32::<BigEndian>(sign_flip).unwrap();
301        buf.into_inner().freeze()
302    }
303}
304
305impl TdbDataType for u64 {
306    fn datatype() -> Datatype {
307        Datatype::UInt64
308    }
309}
310
311impl FromLexical<u64> for u64 {
312    fn from_lexical<B: Buf>(b: B) -> Self {
313        b.reader().read_u64::<BigEndian>().unwrap()
314    }
315}
316
317impl ToLexical<u64> for u64 {
318    fn to_lexical(&self) -> Bytes {
319        let mut buf = BytesMut::new().writer();
320        buf.write_u64::<BigEndian>(*self).unwrap();
321
322        buf.into_inner().freeze()
323    }
324}
325
326const I64_BYTE_MASK: u64 = 0b1000_0000 << (7 * 8);
327impl TdbDataType for i64 {
328    fn datatype() -> Datatype {
329        Datatype::Int64
330    }
331}
332
333impl FromLexical<i64> for i64 {
334    fn from_lexical<B: Buf>(b: B) -> Self {
335        let i = b.reader().read_u64::<BigEndian>().unwrap();
336        (I64_BYTE_MASK ^ i) as i64
337    }
338}
339
340impl ToLexical<i64> for i64 {
341    fn to_lexical(&self) -> Bytes {
342        let sign_flip = I64_BYTE_MASK ^ (*self as u64);
343        let mut buf = BytesMut::new().writer();
344        buf.write_u64::<BigEndian>(sign_flip).unwrap();
345        buf.into_inner().freeze()
346    }
347}
348
349const F32_SIGN_MASK: u32 = 0x8000_0000;
350const F32_COMPLEMENT: u32 = 0xffff_ffff;
351impl TdbDataType for f32 {
352    fn datatype() -> Datatype {
353        Datatype::Float32
354    }
355}
356
357impl FromLexical<f32> for f32 {
358    fn from_lexical<B: Buf>(b: B) -> Self {
359        let i = b.reader().read_u32::<BigEndian>().unwrap();
360        if i & F32_SIGN_MASK > 0 {
361            f32::from_bits(i ^ F32_SIGN_MASK)
362        } else {
363            f32::from_bits(i ^ F32_COMPLEMENT)
364        }
365    }
366}
367
368impl FromLexical<f32> for f64 {
369    fn from_lexical<B: Buf>(b: B) -> Self {
370        f32::from_lexical(b) as f64
371    }
372}
373
374impl ToLexical<f32> for f32 {
375    fn to_lexical(&self) -> Bytes {
376        let f = *self;
377        let g: u32 = if f.signum() == -1.0 {
378            f.to_bits() ^ F32_COMPLEMENT
379        } else {
380            f.to_bits() ^ F32_SIGN_MASK
381        };
382        let mut buf = BytesMut::new().writer();
383        buf.write_u32::<BigEndian>(g).unwrap();
384        buf.into_inner().freeze()
385    }
386}
387
388const F64_SIGN_MASK: u64 = 0x8000_0000_0000_0000;
389const F64_COMPLEMENT: u64 = 0xffff_ffff_ffff_ffff;
390impl TdbDataType for f64 {
391    fn datatype() -> Datatype {
392        Datatype::Float64
393    }
394}
395
396impl FromLexical<f64> for f64 {
397    fn from_lexical<B: Buf>(b: B) -> Self {
398        let i = b.reader().read_u64::<BigEndian>().unwrap();
399        if i & F64_SIGN_MASK > 0 {
400            f64::from_bits(i ^ F64_SIGN_MASK)
401        } else {
402            f64::from_bits(i ^ F64_COMPLEMENT)
403        }
404    }
405}
406
407impl ToLexical<f64> for f64 {
408    fn to_lexical(&self) -> Bytes {
409        let f = *self;
410        let g: u64 = if f.signum() == -1.0 {
411            f.to_bits() ^ F64_COMPLEMENT
412        } else {
413            f.to_bits() ^ F64_SIGN_MASK
414        };
415        let mut buf = BytesMut::new().writer();
416        buf.write_u64::<BigEndian>(g).unwrap();
417        buf.into_inner().freeze()
418    }
419}
420
421impl TdbDataType for Integer {
422    fn datatype() -> Datatype {
423        Datatype::BigInt
424    }
425}
426
427impl FromLexical<Integer> for Integer {
428    fn from_lexical<B: Buf>(mut b: B) -> Self {
429        storage_to_bigint(&mut b)
430    }
431}
432
433impl FromLexical<Integer> for String {
434    fn from_lexical<B: Buf>(mut b: B) -> Self {
435        // TODO make this better
436        storage_to_bigint(&mut b).to_string()
437    }
438}
439
440impl ToLexical<Integer> for Integer {
441    fn to_lexical(&self) -> Bytes {
442        Bytes::from(bigint_to_storage(self.clone()))
443    }
444}
445
446impl TdbDataType for Decimal {
447    fn datatype() -> Datatype {
448        Datatype::Decimal
449    }
450}
451
452impl FromLexical<Decimal> for Decimal {
453    fn from_lexical<B: Buf>(mut b: B) -> Self {
454        Decimal(storage_to_decimal(&mut b))
455    }
456}
457
458impl FromLexical<Decimal> for String {
459    fn from_lexical<B: Buf>(b: B) -> Self {
460        // TODO make this better
461        Decimal::from_lexical(b).0
462    }
463}
464
465impl ToLexical<Decimal> for Decimal {
466    fn to_lexical(&self) -> Bytes {
467        Bytes::from(decimal_to_storage(&self.0))
468    }
469}
470
471impl TdbDataType for bool {
472    fn datatype() -> Datatype {
473        Datatype::Boolean
474    }
475}
476
477impl FromLexical<bool> for bool {
478    fn from_lexical<B: Buf>(mut b: B) -> Self {
479        let num = b.get_u8();
480        num != 0
481    }
482}
483
484impl ToLexical<bool> for bool {
485    fn to_lexical(&self) -> Bytes {
486        if *self {
487            vec![1].into()
488        } else {
489            vec![0].into()
490        }
491    }
492}
493
494impl TdbDataType for NaiveDateTime {
495    fn datatype() -> Datatype {
496        Datatype::DateTime
497    }
498}
499
500impl ToLexical<NaiveDateTime> for NaiveDateTime {
501    fn to_lexical(&self) -> Bytes {
502        Bytes::from(datetime_to_storage(self))
503    }
504}
505
506impl FromLexical<NaiveDateTime> for NaiveDateTime {
507    fn from_lexical<B: Buf>(mut b: B) -> Self {
508        storage_to_datetime(&mut b)
509    }
510}
511
512impl FromLexical<NaiveDateTime> for String {
513    fn from_lexical<B: Buf>(mut b: B) -> Self {
514        let ndt = storage_to_datetime(&mut b);
515        ndt.format("%Y-%m-%dT%H:%M:%S%.fZ").to_string()
516    }
517}
518
519pub struct DateTimeStamp(pub NaiveDateTime);
520
521impl TdbDataType for DateTimeStamp {
522    fn datatype() -> Datatype {
523        Datatype::DateTimeStamp
524    }
525}
526
527impl ToLexical<DateTimeStamp> for DateTimeStamp {
528    fn to_lexical(&self) -> Bytes {
529        Bytes::from(datetime_to_storage(&self.0))
530    }
531}
532
533impl FromLexical<DateTimeStamp> for DateTimeStamp {
534    fn from_lexical<B: Buf>(mut b: B) -> Self {
535        DateTimeStamp(storage_to_datetime(&mut b))
536    }
537}
538
539impl FromLexical<DateTimeStamp> for String {
540    fn from_lexical<B: Buf>(mut b: B) -> Self {
541        let ndt = storage_to_datetime(&mut b);
542        ndt.format("%Y-%m-%dT%H:%M:%S%.fZ").to_string()
543    }
544}
545
546impl TdbDataType for NaiveTime {
547    fn datatype() -> Datatype {
548        Datatype::Time
549    }
550}
551
552impl ToLexical<NaiveTime> for NaiveTime {
553    fn to_lexical(&self) -> Bytes {
554        self.to_string().into()
555    }
556}
557
558impl FromLexical<NaiveTime> for NaiveTime {
559    fn from_lexical<B: Buf>(mut b: B) -> Self {
560        let mut vec = vec![0; b.remaining()];
561        b.copy_to_slice(&mut vec);
562        String::from_utf8(vec)
563            .unwrap()
564            .parse::<NaiveTime>()
565            .unwrap()
566    }
567}
568
569impl FromLexical<NaiveTime> for String {
570    fn from_lexical<B: Buf>(mut b: B) -> Self {
571        let ndt = NaiveTime::from_lexical(&mut b);
572        ndt.format("%H:%M:%S%.fZ").to_string()
573    }
574}
575
576pub struct Date {
577    pub year: i64,
578    pub month: u8,
579    pub day: u8,
580    pub offset: i16,
581}
582
583impl TdbDataType for Date {
584    fn datatype() -> Datatype {
585        Datatype::Date
586    }
587}
588
589impl ToLexical<Date> for Date {
590    fn to_lexical(&self) -> Bytes {
591        let year = self.year.to_lexical();
592        let month = self.month.to_lexical();
593        let day = self.day.to_lexical();
594        let offset = self.offset.to_lexical();
595        [year, month, day, offset].concat().into()
596    }
597}
598
599impl FromLexical<Date> for Date {
600    fn from_lexical<B: Buf>(mut b: B) -> Self {
601        let year = i64::from_lexical(&mut b);
602        let month = u8::from_lexical(&mut b);
603        let day = u8::from_lexical(&mut b);
604        let offset = i16::from_lexical(b);
605        Date {
606            year,
607            month,
608            day,
609            offset,
610        }
611    }
612}
613
614impl FromLexical<Date> for String {
615    fn from_lexical<B: Buf>(b: B) -> Self {
616        let date = Date::from_lexical(b);
617        let year = date.year;
618        let month = date.month;
619        let day = date.day;
620        let offset = offset_string(date.offset);
621        format!("{year:04}-{month:02}-{day:02}{offset:}")
622    }
623}
624
625pub struct GYear {
626    pub year: i64,
627    pub offset: i16,
628}
629
630impl TdbDataType for GYear {
631    fn datatype() -> Datatype {
632        Datatype::GYear
633    }
634}
635
636impl ToLexical<GYear> for GYear {
637    fn to_lexical(&self) -> Bytes {
638        let year = self.year.to_lexical();
639        let offset = self.offset.to_lexical();
640        [year, offset].concat().into()
641    }
642}
643
644impl FromLexical<GYear> for GYear {
645    fn from_lexical<B: Buf>(mut b: B) -> Self {
646        let year = i64::from_lexical(&mut b);
647        let offset = i16::from_lexical(b);
648        GYear { year, offset }
649    }
650}
651
652fn offset_string(offset: i16) -> String {
653    if offset == 0 {
654        "".to_string()
655    } else {
656        let hours = offset / 60;
657        let minutes = offset % 60;
658        if hours < 0 {
659            format!("-{hours:02}:{minutes:02}")
660        } else {
661            format!("+{hours:02}:{minutes:02}")
662        }
663    }
664}
665
666impl FromLexical<GYear> for String {
667    fn from_lexical<B: Buf>(b: B) -> Self {
668        let gyear = GYear::from_lexical(b);
669        let year = gyear.year;
670        let offset = offset_string(gyear.offset);
671        format!("{year:04}{offset:}")
672    }
673}
674
675pub struct GMonth {
676    pub month: u8,
677    pub offset: i16,
678}
679
680impl TdbDataType for GMonth {
681    fn datatype() -> Datatype {
682        Datatype::GMonth
683    }
684}
685
686impl ToLexical<GMonth> for GMonth {
687    fn to_lexical(&self) -> Bytes {
688        let month = self.month.to_lexical();
689        let offset = self.offset.to_lexical();
690        [month, offset].concat().into()
691    }
692}
693
694impl FromLexical<GMonth> for GMonth {
695    fn from_lexical<B: Buf>(mut b: B) -> Self {
696        let month = u8::from_lexical(&mut b);
697        let offset = i16::from_lexical(b);
698        GMonth { month, offset }
699    }
700}
701
702impl FromLexical<GMonth> for String {
703    fn from_lexical<B: Buf>(b: B) -> Self {
704        let gmonth = GMonth::from_lexical(b);
705        let month = gmonth.month;
706        let offset = offset_string(gmonth.offset);
707        format!("--{month:02}{offset:}")
708    }
709}
710
711pub struct GDay {
712    pub day: u8,
713    pub offset: i16,
714}
715
716impl TdbDataType for GDay {
717    fn datatype() -> Datatype {
718        Datatype::GDay
719    }
720}
721
722impl ToLexical<GDay> for GDay {
723    fn to_lexical(&self) -> Bytes {
724        let day = self.day.to_lexical();
725        let offset = self.offset.to_lexical();
726        [day, offset].concat().into()
727    }
728}
729
730impl FromLexical<GDay> for GDay {
731    fn from_lexical<B: Buf>(mut b: B) -> Self {
732        let day = u8::from_lexical(&mut b);
733        let offset = i16::from_lexical(b);
734        GDay { day, offset }
735    }
736}
737
738impl FromLexical<GDay> for String {
739    fn from_lexical<B: Buf>(b: B) -> Self {
740        let gday = GDay::from_lexical(b);
741        let day = gday.day;
742        let offset = offset_string(gday.offset);
743        format!("---{day:02}{offset:}")
744    }
745}
746
747pub struct GYearMonth {
748    pub year: i64,
749    pub month: u8,
750    pub offset: i16,
751}
752
753impl TdbDataType for GYearMonth {
754    fn datatype() -> Datatype {
755        Datatype::GYearMonth
756    }
757}
758
759impl ToLexical<GYearMonth> for GYearMonth {
760    fn to_lexical(&self) -> Bytes {
761        let year = self.year.to_lexical();
762        let month = self.month.to_lexical();
763        let offset = self.offset.to_lexical();
764        [year, month, offset].concat().into()
765    }
766}
767
768impl FromLexical<GYearMonth> for GYearMonth {
769    fn from_lexical<B: Buf>(mut b: B) -> Self {
770        let year = i64::from_lexical(&mut b);
771        let month = u8::from_lexical(&mut b);
772        let offset = i16::from_lexical(b);
773        GYearMonth {
774            year,
775            month,
776            offset,
777        }
778    }
779}
780
781impl FromLexical<GYearMonth> for String {
782    fn from_lexical<B: Buf>(b: B) -> Self {
783        let gyearmonth = GYearMonth::from_lexical(b);
784        let year = gyearmonth.year;
785        let month = gyearmonth.month;
786        let offset = offset_string(gyearmonth.offset);
787        format!("{year:04}-{month:02}{offset:}")
788    }
789}
790
791pub struct GMonthDay {
792    pub month: u8,
793    pub day: u8,
794    pub offset: i16,
795}
796
797impl TdbDataType for GMonthDay {
798    fn datatype() -> Datatype {
799        Datatype::GMonthDay
800    }
801}
802
803impl ToLexical<GMonthDay> for GMonthDay {
804    fn to_lexical(&self) -> Bytes {
805        let month = self.month.to_lexical();
806        let day = self.day.to_lexical();
807        let offset = self.offset.to_lexical();
808        [month, day, offset].concat().into()
809    }
810}
811
812impl FromLexical<GMonthDay> for GMonthDay {
813    fn from_lexical<B: Buf>(mut b: B) -> Self {
814        let month = u8::from_lexical(&mut b);
815        let day = u8::from_lexical(&mut b);
816        let offset = i16::from_lexical(b);
817        GMonthDay { month, day, offset }
818    }
819}
820
821impl FromLexical<GMonthDay> for String {
822    fn from_lexical<B: Buf>(b: B) -> Self {
823        let gmonthday = GMonthDay::from_lexical(b);
824        let month = gmonthday.month;
825        let day = gmonthday.day;
826        let offset = offset_string(gmonthday.offset);
827        format!("--{month:02}-{day:02}{offset:}")
828    }
829}
830
831pub struct Duration {
832    pub sign: i8,
833    pub year: i64,
834    pub month: u8,
835    pub day: u8,
836    pub hour: u8,
837    pub minute: u8,
838    pub second: f64,
839}
840
841impl TdbDataType for Duration {
842    fn datatype() -> Datatype {
843        Datatype::Duration
844    }
845}
846
847impl ToLexical<Duration> for Duration {
848    fn to_lexical(&self) -> Bytes {
849        let sign = self.sign.to_lexical();
850        let year = self.year.to_lexical();
851        let month = self.month.to_lexical();
852        let day = self.day.to_lexical();
853        let hour = self.hour.to_lexical();
854        let minute = self.minute.to_lexical();
855        let second = self.second.to_lexical();
856        [sign, year, month, day, hour, minute, second]
857            .concat()
858            .into()
859    }
860}
861
862impl FromLexical<Duration> for Duration {
863    fn from_lexical<B: Buf>(mut b: B) -> Self {
864        let sign = i8::from_lexical(&mut b);
865        let year = i64::from_lexical(&mut b);
866        let month = u8::from_lexical(&mut b);
867        let day = u8::from_lexical(&mut b);
868        let hour = u8::from_lexical(&mut b);
869        let minute = u8::from_lexical(&mut b);
870        let second: f64 = <f64 as FromLexical<f64>>::from_lexical(&mut b);
871        Duration {
872            sign,
873            year,
874            month,
875            day,
876            hour,
877            minute,
878            second,
879        }
880    }
881}
882
883fn duration_string(duration: &Duration) -> String {
884    let year = if duration.year != 0 {
885        format!("{}Y", duration.year)
886    } else {
887        "".to_string()
888    };
889    let month = if duration.month != 0 {
890        format!("{}M", duration.month)
891    } else {
892        "".to_string()
893    };
894    let day = if duration.day != 0 {
895        format!("{}D", duration.day)
896    } else {
897        "".to_string()
898    };
899    if duration.hour == 0 && duration.minute == 0 && duration.second == 0.0 {
900        format!("P{year}{month}{day}")
901    } else {
902        let hour = if duration.hour != 0 {
903            format!("{}H", duration.hour)
904        } else {
905            "".to_string()
906        };
907        let minute = if duration.minute != 0 {
908            format!("{}M", duration.minute)
909        } else {
910            "".to_string()
911        };
912        let second = if duration.second != 0.0 {
913            format!("{}S", duration.second)
914        } else {
915            "".to_string()
916        };
917        format!("P{year}{month}{day}T{hour}{minute}{second}")
918    }
919}
920
921impl FromLexical<Duration> for String {
922    fn from_lexical<B: Buf>(b: B) -> Self {
923        let duration = Duration::from_lexical(b);
924        duration_string(&duration)
925    }
926}
927
928pub struct YearMonthDuration(pub Duration);
929
930impl TdbDataType for YearMonthDuration {
931    fn datatype() -> Datatype {
932        Datatype::YearMonthDuration
933    }
934}
935
936impl ToLexical<YearMonthDuration> for YearMonthDuration {
937    fn to_lexical(&self) -> Bytes {
938        Duration::to_lexical(&self.0)
939    }
940}
941
942impl FromLexical<YearMonthDuration> for YearMonthDuration {
943    fn from_lexical<B: Buf>(b: B) -> Self {
944        YearMonthDuration(Duration::from_lexical(b))
945    }
946}
947
948impl FromLexical<YearMonthDuration> for String {
949    fn from_lexical<B: Buf>(b: B) -> Self {
950        let duration = Duration::from_lexical(b);
951        duration_string(&duration)
952    }
953}
954
955pub struct DayTimeDuration(pub Duration);
956
957impl TdbDataType for DayTimeDuration {
958    fn datatype() -> Datatype {
959        Datatype::DayTimeDuration
960    }
961}
962
963impl ToLexical<DayTimeDuration> for DayTimeDuration {
964    fn to_lexical(&self) -> Bytes {
965        Duration::to_lexical(&self.0)
966    }
967}
968
969impl FromLexical<DayTimeDuration> for DayTimeDuration {
970    fn from_lexical<B: Buf>(b: B) -> Self {
971        DayTimeDuration(Duration::from_lexical(b))
972    }
973}
974
975impl FromLexical<DayTimeDuration> for String {
976    fn from_lexical<B: Buf>(b: B) -> Self {
977        let duration = Duration::from_lexical(b);
978        duration_string(&duration)
979    }
980}
981
982pub struct Base64Binary(pub Vec<u8>);
983
984impl ToLexical<Base64Binary> for Base64Binary {
985    fn to_lexical(&self) -> Bytes {
986        Bytes::copy_from_slice(&self.0[..])
987    }
988}
989
990impl FromLexical<Base64Binary> for Base64Binary {
991    fn from_lexical<B: Buf>(mut b: B) -> Self {
992        let mut vec = vec![0; b.remaining()];
993        b.copy_to_slice(&mut vec);
994        Base64Binary(vec)
995    }
996}
997
998impl FromLexical<Base64Binary> for String {
999    fn from_lexical<B: Buf>(mut b: B) -> Self {
1000        let mut vec = vec![0; b.remaining()];
1001        b.copy_to_slice(&mut vec);
1002        let wrapper = Base64Display::new(&vec, &base64::engine::general_purpose::STANDARD);
1003        format!("{wrapper}")
1004    }
1005}
1006
1007impl TdbDataType for Base64Binary {
1008    fn datatype() -> Datatype {
1009        Datatype::Base64Binary
1010    }
1011}
1012
1013pub struct HexBinary(pub Vec<u8>);
1014
1015impl ToLexical<HexBinary> for HexBinary {
1016    fn to_lexical(&self) -> Bytes {
1017        Bytes::copy_from_slice(&self.0[..])
1018    }
1019}
1020
1021impl FromLexical<HexBinary> for HexBinary {
1022    fn from_lexical<B: Buf>(mut b: B) -> Self {
1023        let mut vec = vec![0; b.remaining()];
1024        b.copy_to_slice(&mut vec);
1025        HexBinary(vec)
1026    }
1027}
1028
1029impl FromLexical<HexBinary> for String {
1030    fn from_lexical<B: Buf>(mut b: B) -> Self {
1031        let mut vec = vec![0; b.remaining()];
1032        b.copy_to_slice(&mut vec);
1033        hex::encode(vec)
1034    }
1035}
1036
1037impl TdbDataType for HexBinary {
1038    fn datatype() -> Datatype {
1039        Datatype::HexBinary
1040    }
1041}
1042
1043macro_rules! stringy_type {
1044    ($ty:ident) => {
1045        stringy_type!($ty, $ty);
1046    };
1047    ($ty:ident, $datatype:ident) => {
1048        #[derive(PartialEq, Debug)]
1049        pub struct $ty(String);
1050
1051        impl AsRef<str> for $ty {
1052            fn as_ref(&self) -> &str {
1053                &self.0
1054            }
1055        }
1056
1057        impl TdbDataType for $ty {
1058            fn datatype() -> Datatype {
1059                Datatype::$datatype
1060            }
1061        }
1062
1063        impl<T: AsRef<str>> ToLexical<$ty> for T {
1064            fn to_lexical(&self) -> Bytes {
1065                Bytes::copy_from_slice(self.as_ref().as_bytes())
1066            }
1067        }
1068
1069        impl FromLexical<$ty> for $ty {
1070            fn from_lexical<B: Buf>(mut b: B) -> Self {
1071                let mut vec = vec![0; b.remaining()];
1072                b.copy_to_slice(&mut vec);
1073                $ty(String::from_utf8(vec).unwrap())
1074            }
1075        }
1076
1077        impl FromLexical<$ty> for String {
1078            fn from_lexical<B: Buf>(mut b: B) -> Self {
1079                let mut vec = vec![0; b.remaining()];
1080                b.copy_to_slice(&mut vec);
1081                String::from_utf8(vec).unwrap()
1082            }
1083        }
1084    };
1085}
1086
1087macro_rules! biginty_type {
1088    ($ty:ident) => {
1089        biginty_type!($ty, $ty);
1090    };
1091    ($ty:ident, $datatype:ident) => {
1092        #[derive(PartialEq, Debug)]
1093        pub struct $ty(pub Integer);
1094
1095        impl TdbDataType for $ty {
1096            fn datatype() -> Datatype {
1097                Datatype::$datatype
1098            }
1099        }
1100
1101        impl FromLexical<$ty> for $ty {
1102            fn from_lexical<B: Buf>(mut b: B) -> Self {
1103                $ty(storage_to_bigint(&mut b))
1104            }
1105        }
1106
1107        impl FromLexical<$ty> for String {
1108            fn from_lexical<B: Buf>(mut b: B) -> Self {
1109                storage_to_bigint(&mut b).to_string()
1110            }
1111        }
1112
1113        impl FromLexical<$ty> for Integer {
1114            fn from_lexical<B: Buf>(mut b: B) -> Self {
1115                storage_to_bigint(&mut b)
1116            }
1117        }
1118
1119        impl ToLexical<$ty> for $ty {
1120            fn to_lexical(&self) -> Bytes {
1121                Bytes::from(bigint_to_storage(self.0.clone()))
1122            }
1123        }
1124    };
1125}
1126
1127stringy_type!(LangString);
1128stringy_type!(NCName);
1129stringy_type!(Name);
1130stringy_type!(Token);
1131stringy_type!(NMToken);
1132stringy_type!(NormalizedString);
1133stringy_type!(Language);
1134stringy_type!(AnyURI);
1135stringy_type!(Notation);
1136stringy_type!(QName);
1137stringy_type!(ID);
1138stringy_type!(IDRef);
1139stringy_type!(Entity);
1140
1141stringy_type!(AnySimpleType);
1142
1143biginty_type!(PositiveInteger);
1144biginty_type!(NonNegativeInteger);
1145biginty_type!(NegativeInteger);
1146biginty_type!(NonPositiveInteger);