tree_buf/internal/types/
array.rs

1use crate::prelude::*;
2use std::vec::IntoIter;
3
4#[cfg(feature = "encode")]
5impl<T: Encodable> Encodable for Vec<T> {
6    type EncoderArray = VecArrayEncoder<T::EncoderArray>;
7    fn encode_root<O: EncodeOptions>(&self, stream: &mut EncoderStream<'_, O>) -> RootTypeId {
8        profile_method!(encode_root);
9        match self.len() {
10            0 => RootTypeId::Array0,
11            1 => {
12                stream.encode_with_id(|stream| (&self[0]).encode_root(stream));
13                RootTypeId::Array1
14            }
15            _ => {
16                // TODO: Seems kind of redundant to have both the array len,
17                // and the bytes len. Though, it's not for obvious reasons.
18                // Maybe sometimes we can infer from context. Eg: bool always
19                // requires the same number of bits per item
20                encode_usize(self.len(), stream);
21
22                stream.encode_with_id(|stream| T::EncoderArray::encode_all(&self[..], stream));
23
24                RootTypeId::ArrayN
25            }
26        }
27    }
28}
29
30#[cfg(feature = "decode")]
31impl<T: Decodable> Decodable for Vec<T>
32// Overly verbose because of `?` requiring `From` See also ec4fa3ba-def5-44eb-9065-e80b59530af6
33where
34    DecodeError: From<<<T as Decodable>::DecoderArray as DecoderArray>::Error>,
35{
36    type DecoderArray = Option<VecArrayDecoder<T::DecoderArray>>;
37    fn decode(sticks: DynRootBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
38        profile_method!(decode);
39        match sticks {
40            DynRootBranch::Array0 => Ok(Vec::new()),
41            DynRootBranch::Array1(inner) => {
42                let inner = T::decode(*inner, options)?;
43                Ok(vec![inner])
44            }
45            DynRootBranch::Array { len, values } => {
46                let mut v = Vec::with_capacity(len);
47                // TODO: Some of what the code is actually doing here is silly.
48                // Actual DecoderArray's may be IntoIter, which moved out of a Vec
49                // that we wanted in the first place. Specialization here would be nice.
50                let mut decoder = T::DecoderArray::new(values, options)?;
51                for _ in 0..len {
52                    v.push(decoder.decode_next()?);
53                }
54                Ok(v)
55            }
56            _ => Err(DecodeError::SchemaMismatch),
57        }
58    }
59}
60
61#[cfg(feature = "encode")]
62#[derive(Debug, Default)]
63pub struct VecArrayEncoder<T> {
64    // TODO: usize
65    len: <u64 as Encodable>::EncoderArray,
66    // Using Option here enables recursion when necessary.
67    values: Option<T>,
68}
69
70// TODO: usize
71enum FixedOrVariableLength {
72    Fixed(usize),
73    Variable(IntoIter<u64>),
74}
75
76impl FixedOrVariableLength {
77    fn next(&mut self) -> usize {
78        match self {
79            Self::Fixed(v) => *v,
80            Self::Variable(i) => i.decode_next_infallible() as usize,
81        }
82    }
83}
84
85#[cfg(feature = "decode")]
86pub struct VecArrayDecoder<T> {
87    len: FixedOrVariableLength,
88    values: T,
89}
90
91#[cfg(feature = "encode")]
92impl<T: Encodable> EncoderArray<Vec<T>> for VecArrayEncoder<T::EncoderArray> {
93    fn buffer_one<'a, 'b: 'a>(&'a mut self, value: &'b Vec<T>) {
94        self.len.buffer_one(&(value.len() as u64));
95        let values = self.values.get_or_insert_with(Default::default);
96        values.buffer_many(&value[..]);
97    }
98    fn flush<O: EncodeOptions>(self, stream: &mut EncoderStream<'_, O>) -> ArrayTypeId {
99        profile_method!(flush);
100        let Self { len, values } = self;
101        if let Some(values) = values {
102            if len.iter().all(|l| *l == len[0]) {
103                encode_usize(len[0] as usize, stream);
104                stream.encode_with_id(|stream| values.flush(stream));
105                return ArrayTypeId::ArrayFixed;
106            }
107            // TODO: Consider an all-0 type // See also: 84d15459-35e4-4f04-896f-0f4ea9ce52a9
108            stream.encode_with_id(|stream| len.flush(stream));
109            stream.encode_with_id(|stream| values.flush(stream));
110        } else {
111            stream.encode_with_id(|_| ArrayTypeId::Void);
112        }
113
114        ArrayTypeId::ArrayVar
115    }
116}
117
118#[cfg(feature = "decode")]
119impl<T: DecoderArray> DecoderArray for Option<VecArrayDecoder<T>> {
120    type Decode = Vec<T::Decode>;
121    type Error = T::Error;
122
123    fn new(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
124        profile_method!(new);
125
126        match sticks {
127            DynArrayBranch::Array0 => Ok(None),
128            DynArrayBranch::Array { len, values } => {
129                let (values, len) = parallel(
130                    || T::new(*values, options),
131                    || <<u64 as Decodable>::DecoderArray as DecoderArray>::new(*len, options),
132                    options,
133                );
134                let values = values?;
135                let len = FixedOrVariableLength::Variable(len?);
136                Ok(Some(VecArrayDecoder { len, values }))
137            }
138            DynArrayBranch::ArrayFixed { len, values } => Ok(if len == 0 {
139                None
140            } else {
141                let len = FixedOrVariableLength::Fixed(len);
142                let values = T::new(*values, options)?;
143                Some(VecArrayDecoder { len, values })
144            }),
145            _ => Err(DecodeError::SchemaMismatch),
146        }
147    }
148    fn decode_next(&mut self) -> Result<Self::Decode, Self::Error> {
149        if let Some(inner) = self {
150            let len = inner.len.next();
151            let mut result = Vec::with_capacity(len);
152            for _ in 0..len {
153                result.push(inner.values.decode_next()?);
154            }
155            Ok(result)
156        } else {
157            Ok(Vec::new())
158        }
159    }
160}