Skip to content

Commit d470846

Browse files
committed
Merge branch 'master' of github.com:zonyitoo/bson-rs
2 parents 191233e + f47446f commit d470846

File tree

3 files changed

+241
-5
lines changed

3 files changed

+241
-5
lines changed

src/bson.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@
2121

2222
//! BSON definition
2323
24-
use std::collections::BTreeMap;
25-
2624
use chrono::{DateTime, UTC};
2725
use rustc_serialize::json;
2826
use rustc_serialize::hex::ToHex;
2927

28+
use ordered::OrderedDocument;
3029
use spec::{ElementType, BinarySubtype};
3130

3231
/// Possible BSON value types.
@@ -51,8 +50,8 @@ pub enum Bson {
5150

5251
/// Alias for `Vec<Bson>`.
5352
pub type Array = Vec<Bson>;
54-
/// Alias for `BTreeMap<String, Bson>`.
55-
pub type Document = BTreeMap<String, Bson>;
53+
/// Alias for `OrderedDocument`.
54+
pub type Document = OrderedDocument;
5655

5756
impl Bson {
5857
/// Get the `ElementType` of this value.

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,4 @@ pub mod spec;
5454
mod bson;
5555
mod encoder;
5656
mod decoder;
57-
57+
mod ordered;

src/ordered.rs

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
use bson::Bson;
2+
use std::collections::BTreeMap;
3+
use std::iter::{FromIterator, Map};
4+
use std::vec::IntoIter;
5+
use std::slice;
6+
7+
/// A BSON document represented as an associative BTree Map with insertion ordering.
8+
#[derive(Debug, Clone)]
9+
pub struct OrderedDocument {
10+
pub keys: Vec<String>,
11+
document: BTreeMap<String, Bson>,
12+
}
13+
14+
/// An iterator over OrderedDocument entries.
15+
pub struct OrderedDocumentIntoIterator {
16+
vec_iter: IntoIter<String>,
17+
document: BTreeMap<String, Bson>,
18+
}
19+
20+
/// An owning iterator over OrderedDocument entries.
21+
pub struct OrderedDocumentIterator<'a> {
22+
vec_iter: slice::Iter<'a, String>,
23+
document: &'a BTreeMap<String, Bson>,
24+
}
25+
26+
/// An iterator over an OrderedDocument's keys.
27+
pub struct Keys<'a> {
28+
inner: Map<OrderedDocumentIterator<'a>, fn((&'a String, &'a Bson)) -> &'a String>
29+
}
30+
31+
/// An iterator over an OrderedDocument's values.
32+
pub struct Values<'a> {
33+
inner: Map<OrderedDocumentIterator<'a>, fn((&'a String, &'a Bson)) -> &'a Bson>
34+
}
35+
36+
impl<'a> Iterator for Keys<'a> {
37+
type Item = &'a String;
38+
fn next(&mut self) -> Option<(&'a String)> { self.inner.next() }
39+
}
40+
41+
impl<'a> Iterator for Values<'a> {
42+
type Item = &'a Bson;
43+
fn next(&mut self) -> Option<(&'a Bson)> { self.inner.next() }
44+
}
45+
46+
impl IntoIterator for OrderedDocument {
47+
type Item = (String, Bson);
48+
type IntoIter = OrderedDocumentIntoIterator;
49+
50+
fn into_iter(self) -> Self::IntoIter {
51+
OrderedDocumentIntoIterator {
52+
document: self.document,
53+
vec_iter: self.keys.into_iter()
54+
}
55+
}
56+
}
57+
58+
impl<'a> IntoIterator for &'a OrderedDocument {
59+
type Item = (&'a String, &'a Bson);
60+
type IntoIter = OrderedDocumentIterator<'a>;
61+
62+
fn into_iter(self) -> Self::IntoIter {
63+
let ref keys = self.keys;
64+
OrderedDocumentIterator {
65+
vec_iter: keys.into_iter(),
66+
document: &self.document,
67+
}
68+
}
69+
}
70+
71+
impl FromIterator<(String, Bson)> for OrderedDocument {
72+
fn from_iter<T: IntoIterator<Item=(String, Bson)>>(iter: T) -> Self {
73+
let mut doc = OrderedDocument::new();
74+
for (k, v) in iter {
75+
doc.insert(k, v.to_owned());
76+
}
77+
doc
78+
}
79+
}
80+
81+
impl<'a> Iterator for OrderedDocumentIntoIterator {
82+
type Item = (String, Bson);
83+
fn next(&mut self) -> Option<(String, Bson)> {
84+
match self.vec_iter.next() {
85+
Some(key) => {
86+
let val = self.document.remove(&key[..]).unwrap();
87+
Some((key, val.to_owned()))
88+
},
89+
None => None,
90+
}
91+
}
92+
}
93+
94+
impl<'a> Iterator for OrderedDocumentIterator<'a> {
95+
type Item = (&'a String, &'a Bson);
96+
fn next(&mut self) -> Option<(&'a String, &'a Bson)> {
97+
match self.vec_iter.next() {
98+
Some(key) => {
99+
let val = self.document.get(&key[..]).unwrap();
100+
Some((&key, val))
101+
},
102+
None => None,
103+
}
104+
}
105+
}
106+
107+
impl OrderedDocument {
108+
/// Creates a new empty OrderedDocument.
109+
pub fn new() -> OrderedDocument {
110+
OrderedDocument {
111+
keys: Vec::new(),
112+
document: BTreeMap::new(),
113+
}
114+
}
115+
116+
/// Gets an iterator over the entries of the map.
117+
pub fn iter<'a>(&'a self) -> OrderedDocumentIterator<'a> {
118+
self.into_iter()
119+
}
120+
121+
/// Clears the document, removing all values.
122+
pub fn clear(&mut self) {
123+
self.keys.clear();
124+
self.document.clear();
125+
}
126+
127+
/// Returns a reference to the Bson corresponding to the key.
128+
pub fn get(&self, key: &str) -> Option<&Bson> {
129+
self.document.get(key)
130+
}
131+
132+
/// Gets a mutable reference to the value in the entry.
133+
pub fn get_mut(&mut self, key: &str) -> Option<&mut Bson> {
134+
self.document.get_mut(key)
135+
}
136+
137+
/// Returns true if the map contains a value for the specified key.
138+
pub fn contains_key(&self, key: &str) -> bool {
139+
self.document.contains_key(key)
140+
}
141+
142+
/// Returns the position of the key in the ordered vector, if it exists.
143+
pub fn position(&self, key: &str) -> Option<usize> {
144+
self.keys.iter().position(|x| x == key)
145+
}
146+
147+
/// Gets a collection of all keys in the document.
148+
pub fn keys<'a>(&'a self) -> Keys<'a> {
149+
fn first<A, B>((a, _): (A, B)) -> A { a }
150+
let first: fn((&'a String, &'a Bson)) -> &'a String = first;
151+
152+
Keys { inner: self.iter().map(first) }
153+
}
154+
155+
/// Gets a collection of all values in the document.
156+
pub fn values<'a>(&'a self) -> Values<'a> {
157+
fn second<A, B>((_, b): (A, B)) -> B { b }
158+
let second: fn((&'a String, &'a Bson)) -> &'a Bson = second;
159+
160+
Values { inner: self.iter().map(second) }
161+
}
162+
163+
/// Returns the number of elements in the document.
164+
pub fn len(&self) -> usize {
165+
self.keys.len()
166+
}
167+
168+
/// Returns true if the document contains no elements
169+
pub fn is_empty(&self) -> bool {
170+
self.document.is_empty()
171+
}
172+
173+
/// Sets the value of the entry with the OccupiedEntry's key,
174+
/// and returns the entry's old value.
175+
pub fn insert(&mut self, key: String, val: Bson) -> Option<Bson> {
176+
let key_slice = &key[..];
177+
178+
if self.contains_key(key_slice) {
179+
let position = self.position(key_slice).unwrap();
180+
self.keys.remove(position);
181+
}
182+
183+
self.keys.push(key.to_owned());
184+
self.document.insert(key.to_owned(), val.to_owned())
185+
}
186+
187+
/// Takes the value of the entry out of the document, and returns it.
188+
pub fn remove(&mut self, key: &str) -> Option<Bson> {
189+
let position = self.position(key);
190+
if position.is_some() {
191+
self.keys.remove(position.unwrap());
192+
}
193+
self.document.remove(key)
194+
}
195+
}
196+
197+
#[cfg(test)]
198+
mod test {
199+
use super::OrderedDocument;
200+
use bson::Bson;
201+
202+
#[test]
203+
fn ordered_insert() {
204+
let mut doc = OrderedDocument::new();
205+
doc.insert("first".to_owned(), Bson::I32(1));
206+
doc.insert("second".to_owned(), Bson::String("foo".to_owned()));
207+
doc.insert("alphanumeric".to_owned(), Bson::String("bar".to_owned()));
208+
209+
let expected_keys = vec!(
210+
"first".to_owned(),
211+
"second".to_owned(),
212+
"alphanumeric".to_owned(),
213+
);
214+
215+
let keys: Vec<_> = doc.iter().map(|(key, _)| key.to_owned()).collect();
216+
assert_eq!(expected_keys, keys);
217+
}
218+
219+
#[test]
220+
fn remove() {
221+
let mut doc = OrderedDocument::new();
222+
doc.insert("first".to_owned(), Bson::I32(1));
223+
doc.insert("second".to_owned(), Bson::String("foo".to_owned()));
224+
doc.insert("alphanumeric".to_owned(), Bson::String("bar".to_owned()));
225+
226+
assert!(doc.remove("second").is_some());
227+
assert!(doc.remove("none").is_none());
228+
229+
let expected_keys = vec!(
230+
"first",
231+
"alphanumeric",
232+
);
233+
234+
let keys: Vec<_> = doc.iter().map(|(key, _)| key.to_owned()).collect();
235+
assert_eq!(expected_keys, keys);
236+
}
237+
}

0 commit comments

Comments
 (0)