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 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 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);