tree_buf/internal/types/
array.rs1use 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 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>
32where
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 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 len: <u64 as Encodable>::EncoderArray,
66 values: Option<T>,
68}
69
70enum 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 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}