yason/builder/
array.rs

1//! Array builder.
2
3use crate::binary::{
4    ARRAY_SIZE, DATA_TYPE_SIZE, ELEMENT_COUNT_SIZE, MAX_DATA_LENGTH_SIZE, NUMBER_LENGTH_SIZE, VALUE_ENTRY_SIZE,
5};
6use crate::builder::object::InnerObjectBuilder;
7use crate::builder::{BuildResult, Depth, DEFAULT_SIZE, MAX_NESTED_DEPTH};
8use crate::vec::VecExt;
9use crate::yason::{Yason, YasonBuf};
10use crate::{BuildError, DataType, Number, ObjectRefBuilder};
11use decimal_rs::MAX_BINARY_SIZE;
12
13pub(crate) struct InnerArrayBuilder<'a, B: AsMut<Vec<u8>>> {
14    bytes: B,
15    element_count: u16,
16    start_pos: usize,
17    value_entry_pos: usize,
18    value_count: u16,
19    bytes_init_len: usize,
20    current_depth: usize,
21    total_nested_depth: Depth<'a>,
22}
23
24impl<'a, B: AsMut<Vec<u8>>> InnerArrayBuilder<'a, B> {
25    #[inline]
26    pub(crate) fn try_new(mut bytes: B, element_count: u16, mut total_depth: Depth<'a>) -> BuildResult<Self> {
27        if total_depth.depth() >= MAX_NESTED_DEPTH {
28            return Err(BuildError::NestedTooDeeply);
29        }
30
31        let bs = bytes.as_mut();
32        let bytes_init_len = bs.len();
33
34        let size = DATA_TYPE_SIZE + ARRAY_SIZE + ELEMENT_COUNT_SIZE + VALUE_ENTRY_SIZE * element_count as usize;
35        bs.try_reserve(size)?;
36
37        bs.push_data_type(DataType::Array); // type
38        bs.skip_size(); // size
39        let start_pos = bs.len();
40        bs.push_u16(element_count); // element-count
41        let value_entry_pos = bs.len();
42        bs.skip_value_entry(element_count as usize); // value-entry
43
44        total_depth.increase();
45
46        Ok(Self {
47            bytes,
48            element_count,
49            start_pos,
50            value_entry_pos,
51            value_count: 0,
52            bytes_init_len,
53            current_depth: total_depth.depth(),
54            total_nested_depth: total_depth,
55        })
56    }
57
58    #[inline]
59    fn finish(&mut self) -> BuildResult<usize> {
60        if self.current_depth != self.total_nested_depth.depth() {
61            return Err(BuildError::InnerUncompletedError);
62        }
63        if self.value_count != self.element_count {
64            return Err(BuildError::InconsistentElementCount {
65                expected: self.element_count,
66                actual: self.value_count,
67            });
68        }
69
70        let bytes = self.bytes.as_mut();
71        let total_size = bytes.len() - self.start_pos;
72        bytes.write_total_size(total_size as i32, self.start_pos - ARRAY_SIZE);
73
74        self.total_nested_depth.decrease();
75
76        Ok(self.bytes_init_len)
77    }
78
79    #[inline]
80    fn push_value<F>(&mut self, data_type: DataType, f: F) -> BuildResult<()>
81    where
82        F: FnOnce(&mut Vec<u8>, u32, usize) -> BuildResult<()>,
83    {
84        if self.current_depth != self.total_nested_depth.depth() {
85            return Err(BuildError::InnerUncompletedError);
86        }
87
88        let bytes = self.bytes.as_mut();
89        bytes.write_data_type_by_pos(data_type, self.value_entry_pos);
90        let offset = bytes.len() - self.start_pos;
91
92        f(bytes, offset as u32, self.value_entry_pos)?;
93
94        self.value_entry_pos += VALUE_ENTRY_SIZE;
95        self.value_count += 1;
96        Ok(())
97    }
98
99    #[inline]
100    fn push_object(&mut self, element_count: u16, key_sorted: bool) -> BuildResult<InnerObjectBuilder<&mut Vec<u8>>> {
101        let f = |bytes: &mut Vec<u8>, offset: u32, value_entry_pos: usize| {
102            bytes.write_offset(offset, value_entry_pos + DATA_TYPE_SIZE);
103            Ok(())
104        };
105        self.push_value(DataType::Object, f)?;
106
107        let bytes = self.bytes.as_mut();
108        InnerObjectBuilder::try_new(bytes, element_count, key_sorted, self.total_nested_depth.borrow_mut())
109    }
110
111    #[inline]
112    fn push_array(&mut self, element_count: u16) -> BuildResult<InnerArrayBuilder<&mut Vec<u8>>> {
113        let f = |bytes: &mut Vec<u8>, offset: u32, value_entry_pos: usize| {
114            bytes.write_offset(offset, value_entry_pos + DATA_TYPE_SIZE);
115            Ok(())
116        };
117        self.push_value(DataType::Array, f)?;
118
119        let bytes = self.bytes.as_mut();
120        InnerArrayBuilder::try_new(bytes, element_count, self.total_nested_depth.borrow_mut())
121    }
122
123    #[inline]
124    fn push_string(&mut self, value: &str) -> BuildResult<()> {
125        let size = DATA_TYPE_SIZE + MAX_DATA_LENGTH_SIZE + value.len();
126        let f = |bytes: &mut Vec<u8>, offset: u32, value_entry_pos: usize| {
127            bytes.write_offset(offset, value_entry_pos + DATA_TYPE_SIZE);
128            bytes.try_reserve(size)?;
129            bytes.push_data_type(DataType::String);
130            bytes.push_string(value)?;
131            Ok(())
132        };
133        self.push_value(DataType::String, f)
134    }
135
136    #[inline]
137    fn push_number(&mut self, value: &Number) -> BuildResult<()> {
138        let size = DATA_TYPE_SIZE + MAX_BINARY_SIZE + NUMBER_LENGTH_SIZE;
139        let f = |bytes: &mut Vec<u8>, offset: u32, value_entry_pos: usize| {
140            bytes.write_offset(offset, value_entry_pos + DATA_TYPE_SIZE);
141            bytes.try_reserve(size)?;
142            bytes.push_data_type(DataType::Number);
143            bytes.push_number(value);
144            Ok(())
145        };
146        self.push_value(DataType::Number, f)
147    }
148
149    #[inline]
150    fn push_bool(&mut self, value: bool) -> BuildResult<()> {
151        // bool can be inlined
152        let f = |bytes: &mut Vec<u8>, _offset: u32, value_entry_pos: usize| {
153            bytes.write_offset(value as u32, value_entry_pos + DATA_TYPE_SIZE);
154            Ok(())
155        };
156        self.push_value(DataType::Bool, f)
157    }
158
159    #[inline]
160    fn push_null(&mut self) -> BuildResult<()> {
161        // null can be inlined
162        self.push_value(DataType::Null, |_, _, _| Ok(()))
163    }
164
165    #[inline]
166    unsafe fn push_object_or_array(&mut self, yason: &Yason, data_type: DataType) -> BuildResult<()> {
167        let value = yason.as_bytes();
168        let size = value.len();
169        let f = |bytes: &mut Vec<u8>, offset: u32, value_entry_pos: usize| {
170            bytes.write_offset(offset, value_entry_pos + DATA_TYPE_SIZE);
171            bytes.try_reserve(size)?;
172            bytes.extend_from_slice(value);
173            Ok(())
174        };
175        self.push_value(data_type, f)
176    }
177}
178
179/// Builder for encoding an array.
180#[repr(transparent)]
181pub struct ArrayBuilder<'a>(InnerArrayBuilder<'a, Vec<u8>>);
182
183impl ArrayBuilder<'_> {
184    /// Creates `ArrayBuilder` with specified element count.
185    #[inline]
186    pub fn try_new(element_count: u16) -> BuildResult<Self> {
187        let bytes = Vec::try_with_capacity(DEFAULT_SIZE)?;
188        let builder = InnerArrayBuilder::try_new(bytes, element_count, Depth::new())?;
189        Ok(Self(builder))
190    }
191
192    /// Finishes building the array.
193    #[inline]
194    pub fn finish(mut self) -> BuildResult<YasonBuf> {
195        self.0.finish()?;
196        Ok(unsafe { YasonBuf::new_unchecked(self.0.bytes) })
197    }
198}
199
200/// Builder for encoding an array.
201#[repr(transparent)]
202pub struct ArrayRefBuilder<'a>(pub(crate) InnerArrayBuilder<'a, &'a mut Vec<u8>>);
203
204impl<'a> ArrayRefBuilder<'a> {
205    /// Creates `ArrayRefBuilder` with specified element count.
206    #[inline]
207    pub fn try_new(bytes: &'a mut Vec<u8>, element_count: u16) -> BuildResult<Self> {
208        let array_builder = InnerArrayBuilder::try_new(bytes, element_count, Depth::new())?;
209        Ok(Self(array_builder))
210    }
211
212    /// Finishes building the array.
213    #[inline]
214    pub fn finish(mut self) -> BuildResult<&'a Yason> {
215        let bytes_init_len = self.0.finish()?;
216        let bytes = self.0.bytes;
217        Ok(unsafe { Yason::new_unchecked(&bytes[bytes_init_len..]) })
218    }
219
220    #[inline]
221    pub(crate) unsafe fn push_object_or_array(&mut self, yason: &Yason, data_type: DataType) -> BuildResult<&mut Self> {
222        debug_assert!(matches!(yason.data_type().unwrap(), DataType::Object | DataType::Array));
223        debug_assert!(yason.data_type().unwrap() == data_type);
224        self.0.push_object_or_array(yason, data_type)?;
225        Ok(self)
226    }
227}
228
229pub trait ArrBuilder {
230    /// Pushes an embedded object with specified element count and a flag which indicates whether the embedded object is sorted by key.
231    fn push_object(&mut self, element_count: u16, key_sorted: bool) -> BuildResult<ObjectRefBuilder>;
232
233    /// Pushes an embedded array with specified element count.
234    fn push_array(&mut self, element_count: u16) -> BuildResult<ArrayRefBuilder>;
235
236    /// Pushes a string value.
237    fn push_string<Val: AsRef<str>>(&mut self, value: Val) -> BuildResult<&mut Self>;
238
239    /// Pushes a number value.
240    fn push_number<Num: AsRef<Number>>(&mut self, value: Num) -> BuildResult<&mut Self>;
241
242    /// Pushes a bool value.
243    fn push_bool(&mut self, value: bool) -> BuildResult<&mut Self>;
244
245    /// Pushes a null value.
246    fn push_null(&mut self) -> BuildResult<&mut Self>;
247}
248
249macro_rules! impl_push_methods {
250    ($v: vis,) => {
251        /// Pushes an embedded object with specified element count and a flag which indicates whether the embedded object is sorted by key.
252        #[inline]
253        $v fn push_object(&mut self, element_count: u16, key_sorted: bool) -> BuildResult<ObjectRefBuilder> {
254            let obj_builder = self.0.push_object(element_count, key_sorted)?;
255            Ok(ObjectRefBuilder(obj_builder))
256        }
257
258        /// Pushes an embedded array with specified element count.
259        #[inline]
260        $v fn push_array(&mut self, element_count: u16) -> BuildResult<ArrayRefBuilder> {
261            let array_builder = self.0.push_array(element_count)?;
262            Ok(ArrayRefBuilder(array_builder))
263        }
264
265        /// Pushes a string value.
266        #[inline]
267        $v fn push_string<Val: AsRef<str>>(&mut self, value: Val) -> BuildResult<&mut Self> {
268            let value = value.as_ref();
269            self.0.push_string(value)?;
270            Ok(self)
271        }
272
273        /// Pushes a number value.
274        #[inline]
275        $v fn push_number<Num: AsRef<Number>>(&mut self, value: Num) -> BuildResult<&mut Self> {
276            self.0.push_number(value.as_ref())?;
277            Ok(self)
278        }
279
280        /// Pushes a bool value.
281        #[inline]
282        $v fn push_bool(&mut self, value: bool) -> BuildResult<&mut Self> {
283            self.0.push_bool(value)?;
284            Ok(self)
285        }
286
287        /// Pushes a null value.
288        #[inline]
289        $v fn push_null(&mut self) -> BuildResult<&mut Self> {
290            self.0.push_null()?;
291            Ok(self)
292        }
293    };
294}
295
296macro_rules! impl_builder {
297    ($builder: ty) => {
298        impl $builder {
299            impl_push_methods!(pub,);
300        }
301
302        impl ArrBuilder for $builder {
303            impl_push_methods!(,);
304        }
305    };
306}
307
308impl_builder!(ArrayBuilder<'_>);
309impl_builder!(ArrayRefBuilder<'_>);