Coverage Report

Created: 2025-09-05 06:11

/src/bson-rust/src/raw/array_buf.rs
Line
Count
Source (jump to first uncovered line)
1
use std::{
2
    borrow::{Borrow, Cow},
3
    fmt::Debug,
4
};
5
6
use crate::{RawArray, RawBsonRef, RawDocumentBuf};
7
8
use super::{document_buf::BindRawBsonRef, RawArrayIter};
9
10
/// An owned BSON array value (akin to [`std::path::PathBuf`]), backed by a buffer of raw BSON
11
/// bytes. This type can be used to construct owned array values, which can be used to append to
12
/// [`RawDocumentBuf`] or as a field in a [`Deserialize`](serde::Deserialize) struct.
13
///
14
/// Iterating over a [`RawArrayBuf`] yields either an error or a [`RawBson`](crate::raw::RawBson)
15
/// value that borrows from the original document without making any additional allocations.
16
/// ```
17
/// # use bson::error::Error;
18
/// use bson::raw::RawArrayBuf;
19
///
20
/// let mut array = RawArrayBuf::new();
21
/// array.push("a string");
22
/// array.push(12_i32);
23
///
24
/// let mut iter = array.into_iter();
25
///
26
/// let value = iter.next().unwrap()?;
27
/// assert_eq!(value.as_str(), Some("a string"));
28
///
29
/// let value = iter.next().unwrap()?;
30
/// assert_eq!(value.as_i32(), Some(12));
31
///
32
/// assert!(iter.next().is_none());
33
/// # Ok::<(), Error>(())
34
/// ```
35
///
36
/// This type implements [`Deref`](std::ops::Deref) to [`RawArray`], meaning that all methods on
37
/// [`RawArray`] are available on [`RawArrayBuf`] values as well. This includes [`RawArray::get`] or
38
/// any of the type-specific getters, such as [`RawArray::get_object_id`] or [`RawArray::get_str`].
39
/// Note that accessing elements is an O(N) operation, as it requires iterating through the document
40
/// from the beginning to find the requested key.
41
#[derive(Clone, PartialEq)]
42
pub struct RawArrayBuf {
43
    inner: RawDocumentBuf,
44
    len: usize,
45
}
46
47
impl RawArrayBuf {
48
    /// Construct a new, empty [`RawArrayBuf`].
49
0
    pub fn new() -> RawArrayBuf {
50
0
        Self {
51
0
            inner: RawDocumentBuf::new(),
52
0
            len: 0,
53
0
        }
54
0
    }
55
56
    /// Construct a new [`RawArrayBuf`] from the provided [`Vec`] of bytes.
57
    ///
58
    /// This involves a traversal of the array to count the values.
59
83.1k
    pub(crate) fn from_raw_document_buf(doc: RawDocumentBuf) -> Self {
60
83.1k
        let len = doc.iter().count();
61
83.1k
        Self { inner: doc, len }
62
83.1k
    }
63
64
    /// Append a value to the end of the array.
65
    ///
66
    /// ```
67
    /// # use bson::error::Error;
68
    /// use bson::raw::{cstr, RawArrayBuf, RawDocumentBuf};
69
    ///
70
    /// let mut array = RawArrayBuf::new();
71
    /// array.push("a string");
72
    /// array.push(12_i32);
73
    ///
74
    /// let mut doc = RawDocumentBuf::new();
75
    /// doc.append(cstr!("a key"), "a value");
76
    /// array.push(doc.clone());
77
    ///
78
    /// let mut iter = array.into_iter();
79
    ///
80
    /// let value = iter.next().unwrap()?;
81
    /// assert_eq!(value.as_str(), Some("a string"));
82
    ///
83
    /// let value = iter.next().unwrap()?;
84
    /// assert_eq!(value.as_i32(), Some(12));
85
    ///
86
    /// let value = iter.next().unwrap()?;
87
    /// assert_eq!(value.as_document(), Some(doc.as_ref()));
88
    ///
89
    /// assert!(iter.next().is_none());
90
    /// # Ok::<(), Error>(())
91
    /// ```
92
0
    pub fn push(&mut self, value: impl BindRawBsonRef) {
93
0
        self.inner.append(
94
0
            super::CString::from_string_unchecked(self.len.to_string()),
95
0
            value,
96
0
        );
97
0
        self.len += 1;
98
0
    }
99
}
100
101
impl<B: BindRawBsonRef> FromIterator<B> for RawArrayBuf {
102
0
    fn from_iter<T: IntoIterator<Item = B>>(iter: T) -> Self {
103
0
        let mut array_buf = RawArrayBuf::new();
104
0
        for item in iter {
105
0
            array_buf.push(item);
106
0
        }
107
0
        array_buf
108
0
    }
109
}
110
111
impl Debug for RawArrayBuf {
112
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113
0
        f.debug_struct("RawArrayBuf")
114
0
            .field("data", &hex::encode(self.as_bytes()))
115
0
            .field("len", &self.len)
116
0
            .finish()
117
0
    }
118
}
119
120
impl std::ops::Deref for RawArrayBuf {
121
    type Target = RawArray;
122
123
0
    fn deref(&self) -> &Self::Target {
124
0
        RawArray::from_doc(&self.inner)
125
0
    }
126
}
127
128
impl AsRef<RawArray> for RawArrayBuf {
129
83.1k
    fn as_ref(&self) -> &RawArray {
130
83.1k
        RawArray::from_doc(&self.inner)
131
83.1k
    }
132
}
133
134
impl Borrow<RawArray> for RawArrayBuf {
135
0
    fn borrow(&self) -> &RawArray {
136
0
        self.as_ref()
137
0
    }
138
}
139
140
impl<'a> IntoIterator for &'a RawArrayBuf {
141
    type IntoIter = RawArrayIter<'a>;
142
    type Item = super::Result<RawBsonRef<'a>>;
143
144
0
    fn into_iter(self) -> RawArrayIter<'a> {
145
0
        self.as_ref().into_iter()
146
0
    }
147
}
148
149
impl From<RawArrayBuf> for Cow<'_, RawArray> {
150
    fn from(rd: RawArrayBuf) -> Self {
151
        Cow::Owned(rd)
152
    }
153
}
154
155
impl<'a> From<&'a RawArrayBuf> for Cow<'a, RawArray> {
156
    fn from(rd: &'a RawArrayBuf) -> Self {
157
        Cow::Borrowed(rd.as_ref())
158
    }
159
}
160
161
#[cfg(feature = "serde")]
162
impl<'de> serde::Deserialize<'de> for RawArrayBuf {
163
0
    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
164
0
    where
165
0
        D: serde::Deserializer<'de>,
166
0
    {
167
0
        Ok(super::serde::OwnedOrBorrowedRawArray::deserialize(deserializer)?.into_owned())
168
0
    }
169
}
170
171
#[cfg(feature = "serde")]
172
impl serde::Serialize for RawArrayBuf {
173
0
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
174
0
    where
175
0
        S: serde::Serializer,
176
0
    {
177
0
        self.as_ref().serialize(serializer)
178
0
    }
179
}
180
181
impl Default for RawArrayBuf {
182
0
    fn default() -> Self {
183
0
        Self::new()
184
0
    }
185
}
186
187
impl TryFrom<&crate::Array> for RawArrayBuf {
188
    type Error = crate::error::Error;
189
190
0
    fn try_from(value: &crate::Array) -> Result<Self, Self::Error> {
191
0
        Self::try_from(value.clone())
192
0
    }
193
}
194
195
impl TryFrom<crate::Array> for RawArrayBuf {
196
    type Error = crate::error::Error;
197
198
0
    fn try_from(value: crate::Array) -> Result<Self, Self::Error> {
199
0
        let mut tmp = RawArrayBuf::new();
200
0
        for val in value {
201
0
            let raw: super::RawBson = val.try_into()?;
202
0
            tmp.push(raw);
203
        }
204
0
        Ok(tmp)
205
0
    }
206
}