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