codas/
types.rs

1//! Built-in data types and their in-memory
2//! representations.
3//!
4//! # Unstable
5//!
6//! The APIs exposed by this module are _primarily_
7//! used for code generation and dynamic data manipulation;
8//! the exact APIs are subject to change, and may
9//! not be well-optimized.
10use 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/// Enumeration of available built in types.
29#[non_exhaustive]
30#[derive(Debug, Clone, PartialEq)]
31pub enum Type {
32    /// Unsigned (positive) 8-bit number.
33    U8,
34    /// Unsigned (positive) 16-bit number.
35    U16,
36    /// Unsigned (positive) 32-bit number.
37    U32,
38    /// Unsigned (positive) 64-bit number.
39    U64,
40
41    /// Signed (positive or negative) 8-bit number.
42    I8,
43    /// Signed (positive or negative) 16-bit number.
44    I16,
45    /// Signed (positive or negative) 32-bit number.
46    I32,
47    /// Signed (positive or negative) 64-bit number.
48    I64,
49
50    /// 32-bit floating point (decimal) number.
51    F32,
52    /// 64-bit floating point (decimal) number.
53    F64,
54
55    /// Boolean (true or false).
56    Bool,
57
58    /// UTF-8 encoded text.
59    Text,
60
61    /// Data with [`DataType`].
62    Data(DataType),
63
64    /// Data with [`Type`] that's _semantically_ a list.
65    List(Box<Type>),
66
67    /// A mapping between data of two types.
68    Map(Box<(Type, Type)>),
69}
70
71impl Type {
72    /// The type's encoding format.
73    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            // Maps are formatted as a list of keys
91            // followed by a list of values.
92            Type::Map(..) => DataFormat {
93                ordinal: 0,
94                blob_size: 0,
95                data_fields: 2,
96            }
97            .as_format(),
98        }
99    }
100
101    /// Returns the type with `name`.
102    ///
103    /// This function assumes `name` is in ASCII lowercase.
104    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/// In-memory representation of a coda.
130#[derive(Default, Debug, Clone, PartialEq)]
131pub struct Coda {
132    /// The coda's full name, including any
133    /// hierarchical components and separators.
134    pub global_name: Text,
135
136    /// The final component of [`Self::global_name`]
137    /// that does not describe a hierarchy.
138    pub local_name: Text,
139
140    pub docs: Option<Text>,
141
142    /// Data in ascending order by ordinal.
143    pub(crate) data: Vec<DataType>,
144}
145
146impl Coda {
147    /// Returns a new coda containing `data`.
148    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    /// Returns an iterator over all data types in the coda.
158    ///
159    /// The implicit [`crate::types::Unspecified`] data type
160    /// is _not_ included in the returned iterator.
161    pub fn iter(&self) -> impl Iterator<Item = &DataType> {
162        self.data.iter()
163    }
164
165    /// Returns the data type with `name`,
166    /// if it is known by the coda.
167    #[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/// Data containing a structured set of [`DataField`]s.
180#[derive(Default, Debug, Clone, PartialEq)]
181pub struct DataType {
182    /// The name of the data type.
183    ///
184    /// TODO: We've been structuring names similar
185    /// to fully-qualified Rust type names (like `my::data::TypeName`).
186    /// We should standardize on a language-neutral naming
187    /// convention; perhaps HTTP-style URLs (like `/my/data/TypeName`)
188    /// so downstream tools have an easy way to map hierarchical
189    /// names back to native type names as appropriate.
190    pub name: Text,
191
192    /// Markdown-formatted documentation of the data type.
193    pub docs: Option<Text>,
194
195    /// Ordered set of [`Format::Blob`]
196    /// fields in the data type.
197    blob_fields: Vec<DataField>,
198
199    /// Ordered set of [`Format::Data`]
200    /// fields in the data type.
201    ///
202    /// These fields are always encoded, in
203    /// order, _after_ all [`Self::blob_fields`].
204    data_fields: Vec<DataField>,
205
206    /// The encoding format of data with this type.
207    format: Format,
208}
209
210impl DataType {
211    /// Returns a new fixed data type with
212    /// `name`, `ordinal`, `blob_fields`, and `data_fields`.
213    pub fn new(
214        name: Text,
215        docs: Option<Text>,
216        ordinal: FormatMetadata,
217        blob_fields: &[DataField],
218        data_fields: &[DataField],
219    ) -> Self {
220        // Build a new encoding format for the data.
221        let mut format = Format::data(ordinal);
222
223        // Add blob fields to the format.
224        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        // Add data fields to the format.
232        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    /// Returns a new data type with a fluid format.
249    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    /// Returns an iterator over all fields within the type.
260    pub fn iter(&self) -> impl Iterator<Item = &DataField> {
261        self.blob_fields.iter().chain(self.data_fields.iter())
262    }
263
264    /// Adds a new `field` to the type.
265    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    /// Returns the type's encoding format.
285    pub const fn format(&self) -> &Format {
286        &self.format
287    }
288}
289
290/// A field in a [`DataType`].
291#[derive(Default, Clone, Debug, PartialEq)]
292pub struct DataField {
293    /// Name of the field.
294    pub name: Text,
295
296    /// Markdown-formatted documentation of the field.
297    pub docs: Option<Text>,
298
299    /// Type of the field.
300    pub typing: Type,
301
302    /// True if the field is semantically optional.
303    pub optional: bool,
304
305    /// True if the field is semantically flattened.
306    ///
307    /// This property has _no_ effect on the encoding,
308    /// decoding, or in-language representation of
309    /// a field; it's an informational marker that some
310    /// marshallers (like JSON) may use to enable
311    /// compatibility between coda-defined data and
312    /// legacy systems.
313    pub flattened: bool,
314}
315
316/// Unspecified data.
317///
318/// Every coda has an `Unspecified` data type
319/// with ordinal `0`. Data of this type is used
320/// as the default data for every coda.
321///
322/// The exact _contents_ of this data are
323/// entirely unspecified; they could be "null"
324/// or empty (the most common case), or could
325/// contain an undocumented sequence of data.
326/// That's why we call this type `Unspecified`
327/// instead of something like `Null` or `Void`.
328#[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    /// Constant [`DataType`] for unspecified data.
335    pub const DATA_TYPE: DataType = DataType::new_fluid(
336        Text::from("Unspecified"),
337        Some(Text::from("Unspecified data.")),
338    );
339}
340
341/// A thing that _might_ contain data with a
342/// specific format `D`.
343///
344/// This trait is mainly intended for use with the
345/// enums auto-generated for [`Coda`]s
346pub trait TryAsFormat<D> {
347    /// Type of error returned when `self`
348    /// doesn't contain data of format `D`.
349    ///
350    /// This error should be the ordinal
351    /// identifier of the _actual_ data in `D`,
352    /// or [`Infallible`].
353    type Error;
354
355    /// Returns a `D`-formatted reference to the data.
356    fn try_as_format(&self) -> Result<&D, Self::Error>;
357}
358
359/// Every data format can be interpreted as itself.
360impl<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
368// Codecs /////////////////////////////////////////////////
369
370impl 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            // Only data types contain additional encoded info.
384            _ => 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    /// Surprise! The encoding format of unspecified
619    /// data is unspecified (i.e., [`Format::Fluid`]).
620    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    /// Options are a semantic feature that's not
642    /// technically encoded: Optional data encodes
643    /// identically to "not optional" data. In the
644    /// case of `None`, data is encoded and decoded
645    /// as its default value.
646    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        // TODO: It'd be better if we could detect "defaulty-ness"
686        //       during the decoding step, so that we're not having
687        //       to manually compare a decoded value to its default.
688        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    /// Sample data structure for testing type manipulation APIs.
705    #[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    /// Simple data structure intended for nesting
802    /// inside of a [`TestData`].
803    #[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        // Do None values decode as None?
878        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        // Do default values decode as None?
885        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        // Do None values decode as None?
902        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        // Do default values decode as None?
909        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}