Skip to content

Commit 0195fd9

Browse files
committed
temp
1 parent 90199df commit 0195fd9

File tree

6 files changed

+1499
-1505
lines changed

6 files changed

+1499
-1505
lines changed

src/raw/array.rs

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/// A BSON array referencing raw bytes stored elsewhere.
2+
pub struct RawArray {
3+
doc: RawDocumentRef,
4+
}
5+
6+
impl RawArray {
7+
fn new(data: &[u8]) -> RawResult<&RawArray> {
8+
Ok(RawArray::from_doc(RawDocumentRef::new(data)?))
9+
}
10+
11+
fn from_doc(doc: &RawDocumentRef) -> &RawArray {
12+
// SAFETY:
13+
//
14+
// Dereferencing a raw pointer requires unsafe due to the potential that the pointer is
15+
// null, dangling, or misaligned. We know the pointer is not null or dangling due to the
16+
// fact that it's created by a safe reference. Converting &RawDocumentRef to *const
17+
// RawDocumentRef will be properly aligned due to them being references to the same type,
18+
// and converting *const RawDocumentRef to *const RawArray is aligned due to the fact that
19+
// the only field in a RawArray is a RawDocumentRef, meaning the structs are represented
20+
// identically at the byte level.
21+
unsafe { &*(doc as *const RawDocumentRef as *const RawArray) }
22+
}
23+
24+
/// Gets a reference to the value at the given index.
25+
pub fn get(&self, index: usize) -> RawResult<Option<RawBson<'_>>> {
26+
self.into_iter().nth(index).transpose()
27+
}
28+
29+
fn get_with<'a, T>(
30+
&'a self,
31+
index: usize,
32+
f: impl FnOnce(elem::RawBson<'a>) -> RawResult<T>,
33+
) -> RawResult<Option<T>> {
34+
self.get(index)?.map(f).transpose()
35+
}
36+
37+
/// Gets the BSON double at the given index or returns an error if the value at that index isn't
38+
/// a double.
39+
pub fn get_f64(&self, index: usize) -> RawResult<Option<f64>> {
40+
self.get_with(index, elem::RawBson::as_f64)
41+
}
42+
43+
/// Gets a reference to the string at the given index or returns an error if the
44+
/// value at that index isn't a string.
45+
pub fn get_str(&self, index: usize) -> RawResult<Option<&str>> {
46+
self.get_with(index, elem::RawBson::as_str)
47+
}
48+
49+
/// Gets a reference to the document at the given index or returns an error if the
50+
/// value at that index isn't a document.
51+
pub fn get_document(&self, index: usize) -> RawResult<Option<&RawDocumentRef>> {
52+
self.get_with(index, elem::RawBson::as_document)
53+
}
54+
55+
/// Gets a reference to the array at the given index or returns an error if the
56+
/// value at that index isn't a array.
57+
pub fn get_array(&self, index: usize) -> RawResult<Option<&RawArray>> {
58+
self.get_with(index, elem::RawBson::as_array)
59+
}
60+
61+
/// Gets a reference to the BSON binary value at the given index or returns an error if the
62+
/// value at that index isn't a binary.
63+
pub fn get_binary(&self, index: usize) -> RawResult<Option<RawBinary<'_>>> {
64+
self.get_with(index, elem::RawBson::as_binary)
65+
}
66+
67+
/// Gets the ObjectId at the given index or returns an error if the value at that index isn't an
68+
/// ObjectId.
69+
pub fn get_object_id(&self, index: usize) -> RawResult<Option<ObjectId>> {
70+
self.get_with(index, elem::RawBson::as_object_id)
71+
}
72+
73+
/// Gets the boolean at the given index or returns an error if the value at that index isn't a
74+
/// boolean.
75+
pub fn get_bool(&self, index: usize) -> RawResult<Option<bool>> {
76+
self.get_with(index, elem::RawBson::as_bool)
77+
}
78+
79+
/// Gets the DateTime at the given index or returns an error if the value at that index isn't a
80+
/// DateTime.
81+
pub fn get_datetime(&self, index: usize) -> RawResult<Option<DateTime<Utc>>> {
82+
self.get_with(index, elem::RawBson::as_datetime)
83+
}
84+
85+
/// Gets a reference to the BSON regex at the given index or returns an error if the
86+
/// value at that index isn't a regex.
87+
pub fn get_regex(&self, index: usize) -> RawResult<Option<RawRegex<'_>>> {
88+
self.get_with(index, elem::RawBson::as_regex)
89+
}
90+
91+
/// Gets a reference to the BSON timestamp at the given index or returns an error if the
92+
/// value at that index isn't a timestamp.
93+
pub fn get_timestamp(&self, index: usize) -> RawResult<Option<RawTimestamp<'_>>> {
94+
self.get_with(index, elem::RawBson::as_timestamp)
95+
}
96+
97+
/// Gets the BSON int32 at the given index or returns an error if the value at that index isn't
98+
/// a 32-bit integer.
99+
pub fn get_i32(&self, index: usize) -> RawResult<Option<i32>> {
100+
self.get_with(index, elem::RawBson::as_i32)
101+
}
102+
103+
/// Gets BSON int64 at the given index or returns an error if the value at that index isn't a
104+
/// 64-bit integer.
105+
pub fn get_i64(&self, index: usize) -> RawResult<Option<i64>> {
106+
self.get_with(index, elem::RawBson::as_i64)
107+
}
108+
109+
/// Gets a reference to the raw bytes of the RawArray.
110+
pub fn as_bytes(&self) -> &[u8] {
111+
self.doc.as_bytes()
112+
}
113+
}
114+
115+
impl TryFrom<&RawArray> for Vec<Bson> {
116+
type Error = Error;
117+
118+
fn try_from(arr: &RawArray) -> RawResult<Vec<Bson>> {
119+
arr.into_iter()
120+
.map(|result| {
121+
let rawbson = result?;
122+
Bson::try_from(rawbson)
123+
})
124+
.collect()
125+
}
126+
}
127+
128+
impl<'a> IntoIterator for &'a RawArray {
129+
type IntoIter = RawArrayIter<'a>;
130+
type Item = RawResult<elem::RawBson<'a>>;
131+
132+
fn into_iter(self) -> RawArrayIter<'a> {
133+
RawArrayIter {
134+
inner: self.doc.into_iter(),
135+
}
136+
}
137+
}
138+
139+
/// An iterator over borrwed raw BSON array values.
140+
pub struct RawArrayIter<'a> {
141+
inner: RawDocumentIter<'a>,
142+
}
143+
144+
impl<'a> Iterator for RawArrayIter<'a> {
145+
type Item = RawResult<elem::RawBson<'a>>;
146+
147+
fn next(&mut self) -> Option<RawResult<RawBson<'a>>> {
148+
match self.inner.next() {
149+
Some(Ok((_, v))) => Some(Ok(v)),
150+
Some(Err(e)) => Some(Err(e)),
151+
None => None,
152+
}
153+
}
154+
}

0 commit comments

Comments
 (0)