1use core::convert::Infallible;
11
12use alloc::{boxed::Box, vec, vec::Vec};
13
14use crate::codec::{
15 CodecError, DataFormat, DataHeader, Decodable, Encodable, Format, FormatMetadata,
16 ReadsDecodable, WritesEncodable,
17};
18
19pub mod binary;
20pub mod cryptography;
21pub mod dynamic;
22pub mod list;
23pub mod map;
24pub mod number;
25mod text;
26pub use dynamic::Unspecified;
27pub use text::*;
28
29#[non_exhaustive]
31#[derive(Default, Debug, Clone, PartialEq)]
32pub enum Type {
33 #[default]
35 Unspecified,
36
37 U8,
39 U16,
41 U32,
43 U64,
45
46 I8,
48 I16,
50 I32,
52 I64,
54
55 F32,
57 F64,
59
60 Bool,
62
63 Text,
65
66 Data(DataType),
68
69 List(Box<Type>),
71
72 Map(Box<(Type, Type)>),
74}
75
76impl Type {
77 pub const fn format(&self) -> Format {
79 match self {
80 Type::Unspecified => Format::Fluid,
81 Type::U8 => u8::FORMAT,
82 Type::U16 => u16::FORMAT,
83 Type::U32 => u32::FORMAT,
84 Type::U64 => u64::FORMAT,
85 Type::I8 => i8::FORMAT,
86 Type::I16 => i16::FORMAT,
87 Type::I32 => i32::FORMAT,
88 Type::I64 => i64::FORMAT,
89 Type::F32 => f32::FORMAT,
90 Type::F64 => f64::FORMAT,
91 Type::Bool => bool::FORMAT,
92 Type::Text => Text::FORMAT,
93 Type::Data(data) => data.format,
94 Type::List(typing) => typing.format().as_data_format().as_format(),
95
96 Type::Map(..) => DataFormat {
99 ordinal: 0,
100 blob_size: 0,
101 data_fields: 2,
102 }
103 .as_format(),
104 }
105 }
106
107 pub fn from_name(name: &str) -> Option<Self> {
111 match name {
112 "unspecified" => Some(Type::Unspecified),
113 "u8" => Some(Type::U8),
114 "u16" => Some(Type::U16),
115 "u32" => Some(Type::U32),
116 "u64" => Some(Type::U64),
117 "i8" => Some(Type::I8),
118 "i16" => Some(Type::I16),
119 "i32" => Some(Type::I32),
120 "i64" => Some(Type::I64),
121 "f32" => Some(Type::F32),
122 "f64" => Some(Type::F64),
123 "bool" => Some(Type::Bool),
124 "text" => Some(Type::Text),
125 _ => None,
126 }
127 }
128}
129
130#[derive(Default, Debug, Clone, PartialEq)]
132pub struct Coda {
133 pub global_name: Text,
136
137 pub local_name: Text,
140
141 pub docs: Option<Text>,
142
143 pub(crate) data: Vec<DataType>,
145}
146
147impl Coda {
148 pub fn new(global_name: Text, local_name: Text, docs: Option<Text>, data: &[DataType]) -> Self {
150 Self {
151 global_name,
152 local_name,
153 docs,
154 data: Vec::from(data),
155 }
156 }
157
158 pub fn iter(&self) -> impl Iterator<Item = &DataType> {
163 self.data.iter()
164 }
165
166 #[cfg(feature = "parse")]
169 pub(crate) fn type_from_name(&self, name: &str) -> Option<Type> {
170 for data in self.data.iter() {
171 if data.name.eq_ignore_ascii_case(name) {
172 return Some(Type::Data(data.clone()));
173 }
174 }
175
176 Type::from_name(name)
177 }
178}
179
180#[derive(Default, Debug, Clone, PartialEq)]
182pub struct DataType {
183 pub name: Text,
192
193 pub docs: Option<Text>,
195
196 blob_fields: Vec<DataField>,
199
200 data_fields: Vec<DataField>,
206
207 format: Format,
209}
210
211impl DataType {
212 pub fn new(
215 name: Text,
216 docs: Option<Text>,
217 ordinal: FormatMetadata,
218 blob_fields: &[DataField],
219 data_fields: &[DataField],
220 ) -> Self {
221 let mut format = Format::data(ordinal);
223
224 let mut i = 0;
226 while i < blob_fields.len() {
227 let field = &blob_fields[i];
228 format = format.with(field.typing.format());
229 i += 1;
230 }
231
232 let mut i = 0;
234 while i < data_fields.len() {
235 let field = &data_fields[i];
236 format = format.with(field.typing.format());
237 i += 1;
238 }
239
240 Self {
241 name,
242 docs,
243 blob_fields: Vec::from(blob_fields),
244 data_fields: Vec::from(data_fields),
245 format,
246 }
247 }
248
249 pub const fn new_fluid(name: Text, docs: Option<Text>) -> Self {
251 Self {
252 name,
253 docs,
254 blob_fields: vec![],
255 data_fields: vec![],
256 format: Format::Fluid,
257 }
258 }
259
260 pub fn iter(&self) -> impl Iterator<Item = &DataField> {
262 self.blob_fields.iter().chain(self.data_fields.iter())
263 }
264
265 pub fn with(mut self, field: DataField) -> Self {
267 if matches!(self.format, Format::Fluid) {
268 todo!("it should be an error to add fields to a type defined as fluid")
269 }
270
271 let field_format = field.typing.format();
272 self.format = self.format.with(field_format);
273 match field_format {
274 Format::Blob(..) => {
275 self.blob_fields.push(field);
276 }
277 Format::Data(..) | Format::Fluid => {
278 self.data_fields.push(field);
279 }
280 };
281
282 self
283 }
284
285 pub const fn format(&self) -> &Format {
287 &self.format
288 }
289}
290
291#[derive(Default, Clone, Debug, PartialEq)]
293pub struct DataField {
294 pub name: Text,
296
297 pub docs: Option<Text>,
299
300 pub typing: Type,
302
303 pub optional: bool,
305
306 pub flattened: bool,
315}
316
317pub trait TryAsFormat<D> {
323 type Error;
330
331 fn try_as_format(&self) -> Result<&D, Self::Error>;
333}
334
335impl<T> TryAsFormat<T> for T {
337 type Error = Infallible;
338
339 fn try_as_format(&self) -> Result<&T, Self::Error> {
340 Ok(self)
341 }
342}
343
344impl Encodable for Type {
347 const FORMAT: Format = Format::Fluid;
348
349 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
350 match self {
351 Type::Data(typing) => writer.write_data(typing),
352 Type::List(typing) => writer.write_data(typing.as_ref()),
353 Type::Map(typing) => {
354 writer.write_data(&typing.as_ref().0)?;
355 writer.write_data(&typing.as_ref().1)?;
356 Ok(())
357 }
358
359 _ => Ok(()),
361 }
362 }
363
364 fn encode_header(
365 &self,
366 writer: &mut (impl WritesEncodable + ?Sized),
367 ) -> Result<(), CodecError> {
368 let ordinal = match self {
369 Type::Unspecified => 0u16,
370 Type::U8 => 1u16,
371 Type::U16 => 2u16,
372 Type::U32 => 3u16,
373 Type::U64 => 4u16,
374 Type::I8 => 5u16,
375 Type::I16 => 6u16,
376 Type::I32 => 7u16,
377 Type::I64 => 8u16,
378 Type::F32 => 9u16,
379 Type::F64 => 10u16,
380 Type::Bool => 11u16,
381 Type::Text => 12u16,
382 Type::Data(..) => {
383 return DataHeader {
384 count: 1,
385 format: Format::data(13u16).with(Type::FORMAT).as_data_format(),
386 }
387 .encode(writer);
388 }
389 Type::List { .. } => {
390 return DataHeader {
391 count: 1,
392 format: Format::data(14u16).with(Type::FORMAT).as_data_format(),
393 }
394 .encode(writer);
395 }
396 Type::Map { .. } => {
397 return DataHeader {
398 count: 1,
399 format: Format::data(15u16).with(Type::FORMAT).as_data_format(),
400 }
401 .encode(writer);
402 }
403 };
404
405 DataHeader {
406 count: 1,
407 format: Format::data(ordinal).as_data_format(),
408 }
409 .encode(writer)
410 }
411}
412
413impl Decodable for Type {
414 fn decode(
415 &mut self,
416 reader: &mut (impl ReadsDecodable + ?Sized),
417 header: Option<DataHeader>,
418 ) -> Result<(), CodecError> {
419 let header = Self::ensure_header(
420 header,
421 &[
422 0u16, 1u16, 2u16, 3u16, 4u16, 5u16, 6u16, 7u16, 8u16, 9u16, 10u16, 11u16, 12u16,
423 13u16, 14u16, 15u16,
424 ],
425 )?;
426
427 match header.format.ordinal {
428 0u16 => {
429 *self = Type::Unspecified;
430 }
431 1u16 => {
432 *self = Type::U8;
433 }
434 2u16 => {
435 *self = Type::U16;
436 }
437 3u16 => {
438 *self = Type::U32;
439 }
440 4u16 => {
441 *self = Type::U64;
442 }
443 5u16 => {
444 *self = Type::I8;
445 }
446 6u16 => {
447 *self = Type::I16;
448 }
449 7u16 => {
450 *self = Type::I32;
451 }
452 8u16 => {
453 *self = Type::I64;
454 }
455 9u16 => {
456 *self = Type::F32;
457 }
458 10u16 => {
459 *self = Type::F64;
460 }
461 11u16 => {
462 *self = Type::Bool;
463 }
464 12u16 => {
465 *self = Type::Text;
466 }
467 13u16 => {
468 let mut typing = DataType::default();
469 reader.read_data_into(&mut typing)?;
470 *self = Type::Data(typing);
471 }
472 14u16 => {
473 let mut typing = Type::default();
474 reader.read_data_into(&mut typing)?;
475 *self = Type::List(typing.into());
476 }
477 15u16 => {
478 let mut key_typing = Type::default();
479 reader.read_data_into(&mut key_typing)?;
480 let mut value_typing = Type::default();
481 reader.read_data_into(&mut value_typing)?;
482 *self = Type::Map((key_typing, value_typing).into());
483 }
484 _ => unreachable!(),
485 };
486
487 Ok(())
488 }
489}
490
491impl Encodable for Coda {
492 const FORMAT: crate::codec::Format = Format::data(0)
493 .with(Text::FORMAT)
494 .with(Text::FORMAT)
495 .with(Text::FORMAT)
496 .with(Vec::<DataType>::FORMAT);
497
498 fn encode(
499 &self,
500 writer: &mut (impl crate::codec::WritesEncodable + ?Sized),
501 ) -> Result<(), crate::codec::CodecError> {
502 writer.write_data(&self.global_name)?;
503 writer.write_data(&self.local_name)?;
504 writer.write_data(&self.docs)?;
505 writer.write_data(&self.data)?;
506 Ok(())
507 }
508}
509
510impl Decodable for Coda {
511 fn decode(
512 &mut self,
513 reader: &mut (impl crate::codec::ReadsDecodable + ?Sized),
514 header: Option<crate::codec::DataHeader>,
515 ) -> Result<(), crate::codec::CodecError> {
516 let _ = Self::ensure_header(header, &[0u16])?;
517
518 reader.read_data_into(&mut self.global_name)?;
519 reader.read_data_into(&mut self.local_name)?;
520 reader.read_data_into(&mut self.docs)?;
521 reader.read_data_into(&mut self.data)?;
522
523 Ok(())
524 }
525}
526
527impl Encodable for DataType {
528 const FORMAT: Format = Format::data(0)
529 .with(Text::FORMAT)
530 .with(Option::<Text>::FORMAT)
531 .with(Vec::<DataField>::FORMAT)
532 .with(Vec::<DataField>::FORMAT)
533 .with(Format::FORMAT);
534
535 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
536 writer.write_data(&self.name)?;
537 writer.write_data(&self.docs)?;
538 writer.write_data(&self.blob_fields)?;
539 writer.write_data(&self.data_fields)?;
540 writer.write_data(&self.format)?;
541 Ok(())
542 }
543}
544
545impl Decodable for DataType {
546 fn decode(
547 &mut self,
548 reader: &mut (impl ReadsDecodable + ?Sized),
549 header: Option<DataHeader>,
550 ) -> Result<(), CodecError> {
551 let _ = Self::ensure_header(header, &[0])?;
552
553 reader.read_data_into(&mut self.name)?;
554 reader.read_data_into(&mut self.docs)?;
555 reader.read_data_into(&mut self.blob_fields)?;
556 reader.read_data_into(&mut self.data_fields)?;
557 reader.read_data_into(&mut self.format)?;
558
559 Ok(())
560 }
561}
562
563impl Encodable for DataField {
564 const FORMAT: Format = Format::data(0)
565 .with(bool::FORMAT)
566 .with(bool::FORMAT)
567 .with(Text::FORMAT)
568 .with(Option::<Text>::FORMAT)
569 .with(Type::FORMAT);
570
571 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
572 writer.write_data(&self.optional)?;
573 writer.write_data(&self.flattened)?;
574 writer.write_data(&self.name)?;
575 writer.write_data(&self.docs)?;
576 writer.write_data(&self.typing)?;
577 Ok(())
578 }
579}
580
581impl Decodable for DataField {
582 fn decode(
583 &mut self,
584 reader: &mut (impl ReadsDecodable + ?Sized),
585 header: Option<DataHeader>,
586 ) -> Result<(), CodecError> {
587 let _ = Self::ensure_header(header, &[0])?;
588 reader.read_data_into(&mut self.optional)?;
589 reader.read_data_into(&mut self.flattened)?;
590 reader.read_data_into(&mut self.name)?;
591 reader.read_data_into(&mut self.docs)?;
592 reader.read_data_into(&mut self.typing)?;
593 Ok(())
594 }
595}
596
597impl<T> Encodable for Option<T>
598where
599 T: Default + Encodable + 'static,
600{
601 const FORMAT: Format = T::FORMAT;
607
608 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
609 match &self {
610 Some(value) => {
611 value.encode(writer)?;
612 }
613
614 None => {
615 Self::FORMAT.encode_default_value(writer)?;
616 }
617 }
618
619 Ok(())
620 }
621
622 fn encode_header(
623 &self,
624 writer: &mut (impl WritesEncodable + ?Sized),
625 ) -> Result<(), CodecError> {
626 match &self {
627 Some(value) => value.encode_header(writer),
628 None => Self::FORMAT.encode_default_header(writer),
629 }
630 }
631}
632
633impl<T> Decodable for Option<T>
634where
635 T: Decodable + Default + PartialEq + 'static,
636{
637 fn decode(
638 &mut self,
639 reader: &mut (impl ReadsDecodable + ?Sized),
640 header: Option<DataHeader>,
641 ) -> Result<(), CodecError> {
642 let mut decoded = T::default();
643 decoded.decode(reader, header)?;
644
645 if decoded == T::default() {
649 *self = None;
650 } else {
651 *self = Some(decoded);
652 }
653
654 Ok(())
655 }
656}
657
658#[cfg(test)]
659mod tests {
660 use crate::codec::{Decodable, WritesEncodable};
661
662 use super::*;
663
664 #[derive(Clone, Debug, Default, PartialEq)]
666 pub struct TestData {
667 pub number: i32,
668 pub floaty: f64,
669 pub text_list: Vec<Text>,
670 pub text: Text,
671 pub nested: NestedTestData,
672 pub two_d: Vec<Vec<Text>>,
673 }
674
675 impl TestData {
676 pub fn typing() -> DataType {
677 let blob_fields = vec![
678 DataField {
679 name: Text::from("number"),
680 docs: None,
681 typing: Type::I32,
682 optional: false,
683 flattened: false,
684 },
685 DataField {
686 name: Text::from("floaty"),
687 docs: None,
688 typing: Type::F64,
689 optional: false,
690 flattened: false,
691 },
692 ];
693
694 let data_fields = vec![
695 DataField {
696 name: Text::from("text_list"),
697 docs: None,
698 typing: Type::List(Type::Text.into()),
699 optional: false,
700 flattened: false,
701 },
702 DataField {
703 name: Text::from("text"),
704 docs: None,
705 typing: Type::Text,
706 optional: false,
707 flattened: false,
708 },
709 DataField {
710 name: Text::from("nested"),
711 docs: None,
712 typing: Type::Data(NestedTestData::typing()),
713 optional: false,
714 flattened: false,
715 },
716 DataField {
717 name: Text::from("two_d"),
718 docs: None,
719 typing: Type::List(Type::List(Type::Text.into()).into()),
720 optional: false,
721 flattened: false,
722 },
723 ];
724
725 let typing = DataType::new(Text::from("Testdata"), None, 1, &blob_fields, &data_fields);
726
727 assert_eq!(Self::FORMAT, *typing.format());
728
729 typing
730 }
731 }
732
733 impl Encodable for TestData {
734 const FORMAT: Format = Format::data(1)
735 .with(i32::FORMAT)
736 .with(f64::FORMAT)
737 .with(Vec::<Text>::FORMAT)
738 .with(Text::FORMAT)
739 .with(NestedTestData::FORMAT)
740 .with(Vec::<Vec<Text>>::FORMAT);
741
742 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
743 writer.write_data(&self.number)?;
744 writer.write_data(&self.floaty)?;
745 writer.write_data(&self.text_list)?;
746 writer.write_data(&self.text)?;
747 writer.write_data(&self.nested)?;
748 writer.write_data(&self.two_d)?;
749 Ok(())
750 }
751 }
752
753 impl Decodable for TestData {
754 fn decode(
755 &mut self,
756 reader: &mut (impl ReadsDecodable + ?Sized),
757 header: Option<DataHeader>,
758 ) -> Result<(), CodecError> {
759 let _ = Self::ensure_header(header, &[1])?;
760
761 reader.read_data_into(&mut self.number)?;
762 reader.read_data_into(&mut self.floaty)?;
763 reader.read_data_into(&mut self.text_list)?;
764 reader.read_data_into(&mut self.text)?;
765 reader.read_data_into(&mut self.nested)?;
766 reader.read_data_into(&mut self.two_d)?;
767
768 Ok(())
769 }
770 }
771
772 #[derive(Clone, Debug, Default, PartialEq)]
775 pub struct NestedTestData {
776 pub boolean: bool,
777 }
778
779 impl NestedTestData {
780 pub fn typing() -> DataType {
781 let blob_fields = vec![DataField {
782 name: Text::from("boolean"),
783 docs: None,
784 typing: Type::Bool,
785 optional: false,
786 flattened: false,
787 }];
788
789 let data_fields = vec![];
790
791 let typing = DataType::new(
792 Text::from("NestedTestdata"),
793 None,
794 2,
795 &blob_fields,
796 &data_fields,
797 );
798
799 assert_eq!(Self::FORMAT, *typing.format());
800
801 typing
802 }
803 }
804
805 impl Encodable for NestedTestData {
806 const FORMAT: Format = Format::data(2).with(bool::FORMAT);
807
808 fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
809 writer.write_data(&self.boolean)?;
810 Ok(())
811 }
812 }
813
814 impl Decodable for NestedTestData {
815 fn decode(
816 &mut self,
817 reader: &mut (impl ReadsDecodable + ?Sized),
818 header: Option<DataHeader>,
819 ) -> Result<(), CodecError> {
820 let _ = Self::ensure_header(header, &[2])?;
821
822 reader.read_data_into(&mut self.boolean)?;
823
824 Ok(())
825 }
826 }
827
828 #[test]
829 pub fn data_type_codec() {
830 let data_type = TestData::typing();
831
832 let mut encoded_data_type = vec![];
833 encoded_data_type.write_data(&data_type).unwrap();
834 let decoded_data_type = encoded_data_type.as_slice().read_data().unwrap();
835
836 assert_eq!(data_type, decoded_data_type);
837 }
838
839 #[test]
840 fn codes_unstructured_optionals() {
841 let option: Option<u32> = Some(1337u32);
842 let mut data = vec![];
843 data.write_data(&option).expect("encoded");
844 println!("encoded");
845 let decoded_option = data.as_slice().read_data().expect("decoded");
846 assert_eq!(option, decoded_option);
847
848 let option: Option<u32> = None;
850 let mut data = vec![];
851 data.write_data(&option).expect("encoded");
852 let decoded_option = data.as_slice().read_data().expect("decoded");
853 assert_eq!(option, decoded_option);
854
855 let option: Option<u32> = Some(0);
857 let mut data = vec![];
858 data.write_data(&option).expect("encoded");
859 let decoded_option: Option<u32> = data.as_slice().read_data().expect("decoded");
860 assert_eq!(None, decoded_option);
861 }
862
863 #[test]
864 fn codes_structured_optionals() {
865 let option: Option<Text> = Some("Hello, World!".into());
866 let mut data = vec![];
867 data.write_data(&option).expect("encoded");
868 println!("encoded");
869 let decoded_option = data.as_slice().read_data().expect("decoded");
870 assert_eq!(option, decoded_option);
871
872 let option: Option<Text> = None;
874 let mut data = vec![];
875 data.write_data(&option).expect("encoded");
876 let decoded_option = data.as_slice().read_data().expect("decoded");
877 assert_eq!(option, decoded_option);
878
879 let option: Option<Text> = Some("".into());
881 let mut data = vec![];
882 data.write_data(&option).expect("encoded");
883 let decoded_option: Option<Text> = data.as_slice().read_data().expect("decoded");
884 assert_eq!(None, decoded_option);
885 }
886}