codas/types/
list.rs

1//! List data types (including `[u8]` and `Option`).
2
3use alloc::vec::Vec;
4
5use crate::codec::{
6    CodecError, DataFormat, DataHeader, Decodable, Encodable, Format, FormatMetadata,
7    ReadsDecodable, WritesEncodable,
8};
9
10impl Encodable for [u8] {
11    /// Encoded as a sequence of [`slice::len`]
12    /// [`Format::Data`], each containing a
13    /// single [`u8`] from the slice.
14    const FORMAT: Format = u8::FORMAT.as_data_format().as_format();
15
16    fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
17        writer.write_all(self)?;
18        Ok(())
19    }
20
21    fn encode_header(
22        &self,
23        writer: &mut (impl WritesEncodable + ?Sized),
24    ) -> Result<(), CodecError> {
25        DataHeader {
26            count: self.len() as FormatMetadata,
27            format: DataFormat {
28                ordinal: 0,
29                blob_size: 1,
30                data_fields: 0,
31            },
32        }
33        .encode(writer)
34    }
35}
36
37impl<T> Encodable for Vec<T>
38where
39    T: Encodable + 'static,
40{
41    /// Encoded as a sequence of [`Vec::len`] [`Format::Data`]
42    /// containing `T`'s [`Encodable::FORMAT`].
43    ///
44    /// The encoding format of vectors is linked to the
45    /// format of \[[`u8`]\]s: A `vec![1337u8]` and
46    /// `&[1337u8]` should have identical encodings.
47    const FORMAT: Format = T::FORMAT.as_data_format().as_format();
48
49    fn encode(&self, writer: &mut (impl WritesEncodable + ?Sized)) -> Result<(), CodecError> {
50        for item in self {
51            writer.write_data(item)?;
52        }
53
54        Ok(())
55    }
56
57    fn encode_header(
58        &self,
59        writer: &mut (impl WritesEncodable + ?Sized),
60    ) -> Result<(), CodecError> {
61        DataHeader {
62            count: self.len() as FormatMetadata,
63            format: Self::FORMAT.as_data_format(),
64        }
65        .encode(writer)
66    }
67}
68
69impl<T> Decodable for Vec<T>
70where
71    T: Decodable + Default + 'static,
72{
73    fn decode(
74        &mut self,
75        reader: &mut (impl ReadsDecodable + ?Sized),
76        header: Option<DataHeader>,
77    ) -> Result<(), CodecError> {
78        let header = Self::ensure_header(header, &[0])?;
79
80        // To mitigate repeat allocations, reserve
81        // space for any elements in excess of this
82        // vector's current capacity.
83        let count = header.count as usize;
84        if self.capacity() < count {
85            self.reserve_exact(count - self.capacity());
86        }
87
88        // Decode all elements.
89        for i in 0..count {
90            let mut item = self.get_mut(i);
91            if item.is_none() {
92                self.push(T::default());
93                item = Some(self.get_mut(i).expect("must exist"));
94            }
95            let item = item.unwrap();
96
97            reader.read_data_into(item)?;
98        }
99
100        self.truncate(count);
101
102        Ok(())
103    }
104}
105
106#[cfg(test)]
107mod test {
108    use crate::{
109        codec::{ReadsDecodable, WritesEncodable},
110        types::Text,
111    };
112
113    #[test]
114    fn codes_u8_slices() {
115        let value = &[8u8, 3, 7][..];
116        let mut encoded = vec![];
117        encoded.write_data(value).expect("encoded");
118        let decoded: Vec<u8> = encoded.as_slice().read_data().expect("decoded");
119        assert_eq!(value, decoded.as_slice());
120    }
121
122    #[test]
123    fn codes_unstructured_vecs() {
124        let value = vec![7u32, 8, 9];
125        let mut encoded = vec![];
126        encoded.write_data(&value).expect("encoded");
127        let decoded: Vec<u32> = encoded.as_slice().read_data().expect("decoded");
128        assert_eq!(value, decoded);
129    }
130
131    #[test]
132    fn codes_structured_vecs() {
133        let value = vec![Text::from("Hello, world!")];
134        let mut encoded = vec![];
135        encoded.write_data(&value).expect("encoded");
136        let decoded: Vec<Text> = encoded.as_slice().read_data().expect("decoded");
137        assert_eq!(value, decoded);
138    }
139}