binn_rs/
container.rs

1use crate::error::Result;
2use crate::raw_container::{Key, KeyType, RawContainer};
3use crate::value::AsValue;
4use crate::Allocation;
5use crate::{Error, Value};
6
7const EMPTY_LIST: &[u8] = &[0xE0, 0x03, 0x00];
8const EMPTY_MAP: &[u8] = &[0xE1, 0x03, 0x00];
9const EMPTY_OBJ: &[u8] = &[0xE2, 0x03, 0x00];
10
11/// Container that stores its elements sequentially and provides
12/// *get by position* access
13#[derive(Debug, Eq, PartialEq)]
14pub struct List<'a> {
15    pub(crate) inner: RawContainer<'a>,
16}
17
18/// Container that stores its elements with numeric keys and provides
19/// *get by key* access. Keys are of `i32` type
20#[derive(Debug, Eq, PartialEq)]
21pub struct Map<'a> {
22    pub(crate) inner: RawContainer<'a>,
23}
24
25/// Container that stores its elements with numeric keys and provides
26/// *get by key* access. Keys are of `&str` type
27#[derive(Debug, Eq, PartialEq)]
28pub struct Object<'a> {
29    pub(crate) inner: RawContainer<'a>,
30}
31
32impl<'a> List<'a> {
33    /// Adds new value to this list
34    pub fn add_value<'c, 'p: 'c, 'd>(&'p mut self, value: impl AsValue<'d>) -> Result<Value<'c>> {
35        self.inner.add_value(Key::Empty, value)
36    }
37
38    /// Returns slice of bytes representing current document.
39    ///
40    /// It's guaranteed to be subslice of initial buffer
41    /// and for root document it will starting at 0.
42    ///
43    /// So by taking it's len you can get how many bytes in buffer are used
44    pub fn as_bytes(&self) -> &[u8] {
45        self.inner.as_bytes()
46    }
47
48    /// Returns number of elements in this list
49    pub fn count(&self) -> usize {
50        self.inner.count()
51    }
52
53    /// Returns new empty list
54    ///
55    /// List is read only so no new elements can be added to it
56    pub fn empty() -> List<'static> {
57        // EMPTY_LIST can't be malformed
58        List {
59            inner: RawContainer::from_bytes(EMPTY_LIST, KeyType::Empty).unwrap(),
60        }
61    }
62
63    /// Creates a new list that uses given allocation for storage
64    pub fn empty_mut(allocation: impl Into<Allocation<'a>>) -> Result<Self> {
65        Ok(Self {
66            inner: empty_mut(allocation.into(), EMPTY_LIST, KeyType::Empty)?,
67        })
68    }
69
70    /// Get value at position
71    pub fn get(&self, pos: usize) -> Option<Value<'_>> {
72        self.inner.get_at(pos)
73    }
74
75    /// Iterate over elements of this list
76    pub fn iter(&self) -> impl Iterator<Item = Value<'_>> {
77        self.inner.iter().map(|(_, v)| v)
78    }
79}
80
81impl<'a> Map<'a> {
82    /// Adds new field with given name and value to this object
83    pub fn add_value<'c, 'p: 'c, 'd>(
84        &'p mut self,
85        key: i32,
86        value: impl AsValue<'d>,
87    ) -> Result<Value<'c>> {
88        self.inner.add_value(Key::Num(key), value)
89    }
90
91    /// Returns slice of bytes representing current document.
92    ///
93    /// It's guaranteed to be subslice of initial buffer
94    /// and for root document it will starting at 0.
95    ///
96    /// So by taking it's len you can get how many bytes in buffer are used
97    pub fn as_bytes(&self) -> &[u8] {
98        self.inner.as_bytes()
99    }
100
101    /// Returns number of elements in this map
102    pub fn count(&self) -> usize {
103        self.inner.count()
104    }
105
106    /// Returns new empty object
107    ///
108    /// Object is read only so no new elements can be added to it
109    pub fn empty() -> Map<'static> {
110        // EMPTY_MAP can't be malformed
111        Map {
112            inner: RawContainer::from_bytes(EMPTY_MAP, KeyType::Num).unwrap(),
113        }
114    }
115
116    /// Creates a new object that uses given allocation for storage
117    pub fn empty_mut(allocation: impl Into<Allocation<'a>>) -> Result<Self> {
118        Ok(Self {
119            inner: empty_mut(allocation.into(), EMPTY_MAP, KeyType::Num)?,
120        })
121    }
122
123    /// Get value with specific key
124    pub fn get(&self, key: i32) -> Option<Value<'_>> {
125        self.inner.get(Key::Num(key))
126    }
127
128    /// Iterate over elements of this map
129    pub fn iter(&self) -> impl Iterator<Item = (i32, Value<'_>)> {
130        self.inner.iter().map(|(k, v)| (k.to_num().unwrap(), v))
131    }
132}
133
134impl<'a> Object<'a> {
135    /// Adds new field with given name and value to this object
136    pub fn add_value<'c, 'p: 'c, 'd>(
137        &'p mut self,
138        key: &str,
139        value: impl AsValue<'d>,
140    ) -> Result<Value<'c>> {
141        self.inner.add_value(Key::Str(key), value)
142    }
143
144    /// Returns slice of bytes representing current document.
145    ///
146    /// It's guaranteed to be subslice of initial buffer
147    /// and for root document it will starting at 0.
148    ///
149    /// So by taking it's len you can get how many bytes in buffer are used
150    pub fn as_bytes(&self) -> &[u8] {
151        self.inner.as_bytes()
152    }
153
154    /// Returns number of elements in this object
155    pub fn count(&self) -> usize {
156        self.inner.count()
157    }
158
159    /// Returns new empty object
160    ///
161    /// Object is read only so no new elements can be added to it
162    pub fn empty() -> Object<'static> {
163        // EMPTY_OBJ can't be malformed
164        Object {
165            inner: RawContainer::from_bytes(EMPTY_OBJ, KeyType::Str).unwrap(),
166        }
167    }
168
169    /// Creates a new object that uses given allocation for storage
170    pub fn empty_mut(allocation: impl Into<Allocation<'a>>) -> Result<Self> {
171        Ok(Self {
172            inner: empty_mut(allocation.into(), EMPTY_OBJ, KeyType::Str)?,
173        })
174    }
175
176    /// Get value with specific key
177    pub fn get(&self, key: &str) -> Option<Value<'_>> {
178        self.inner.get(Key::Str(key))
179    }
180
181    /// Iterate over elements of this object
182    pub fn iter(&self) -> impl Iterator<Item = (&str, Value<'_>)> {
183        self.inner.iter().map(|(k, v)| (k.to_str().unwrap(), v))
184    }
185}
186
187/// Helper function to create mutable container from given source
188fn empty_mut<'a>(
189    mut allocation: Allocation<'a>,
190    source: &[u8],
191    key_type: KeyType,
192) -> Result<RawContainer<'a>> {
193    let len = source.len();
194    match &mut allocation {
195        Allocation::Static(buf) => {
196            if buf.len() < len {
197                return Err(Error::SmallBuffer(len - buf.len()));
198            }
199            buf[..len].copy_from_slice(source);
200        }
201    }
202
203    Ok(RawContainer::new_mut(allocation, key_type).unwrap())
204}
205
206impl<'a> AsValue<'a> for List<'a> {
207    fn to_value(self) -> Value<'a> {
208        let inner = self.inner.clone();
209        Value::List(List { inner })
210    }
211}
212
213impl<'a> AsValue<'a> for Map<'a> {
214    fn to_value(self) -> Value<'a> {
215        let inner = self.inner.clone();
216        Value::Map(Map { inner })
217    }
218}
219
220impl<'a> AsValue<'a> for Object<'a> {
221    fn to_value(self) -> Value<'a> {
222        let inner = self.inner.clone();
223        Value::Object(Object { inner })
224    }
225}