Skip to content

Commit f1a08f8

Browse files
authored
RUST-622 Add document square bracket indexing (#503)
1 parent e0c5ca5 commit f1a08f8

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/bson.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use std::{
2525
convert::{TryFrom, TryInto},
2626
fmt::{self, Debug, Display, Formatter},
2727
hash::Hash,
28+
ops::Index,
2829
};
2930

3031
use serde_json::{json, Value};
@@ -236,6 +237,20 @@ impl Debug for Bson {
236237
}
237238
}
238239

240+
impl Index<&str> for Bson {
241+
type Output = Bson;
242+
243+
fn index(&self, index: &str) -> &Self::Output {
244+
match *self {
245+
Bson::Document(ref doc) => match doc.get(index) {
246+
Some(v) => v,
247+
None => &Bson::Null,
248+
},
249+
_ => &Bson::Null,
250+
}
251+
}
252+
}
253+
239254
impl From<f32> for Bson {
240255
fn from(a: f32) -> Bson {
241256
Bson::Double(a.into())

src/document.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::{
77
fmt::{self, Debug, Display, Formatter},
88
io::{Read, Write},
99
iter::{Extend, FromIterator, IntoIterator},
10+
ops::Index,
1011
};
1112

1213
use ahash::RandomState;
@@ -139,6 +140,17 @@ impl Debug for Document {
139140
}
140141
}
141142

143+
impl Index<&str> for Document {
144+
type Output = Bson;
145+
146+
fn index(&self, index: &str) -> &Self::Output {
147+
match self.get(index) {
148+
Some(v) => v,
149+
None => &Bson::Null,
150+
}
151+
}
152+
}
153+
142154
/// An iterator over Document entries.
143155
pub struct IntoIter {
144156
inner: indexmap::map::IntoIter<String, Bson>,

src/tests/modules/document.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,48 @@ fn test_pretty_printing() {
370370
}"#;
371371
assert_eq!(expected, format!("{d:#}"));
372372
}
373+
374+
#[test]
375+
fn test_indexing() {
376+
let d = doc! {"x": 1};
377+
let val = d["x"].as_i32().unwrap();
378+
assert_eq!(val, 1);
379+
380+
let d = doc! {"x": {"y": 100}};
381+
let val = d["x"]["y"].as_i32().unwrap();
382+
assert_eq!(val, 100);
383+
384+
let d = doc! {"x" : true};
385+
let val = d["x"].as_bool().unwrap();
386+
assert!(val);
387+
388+
let d = doc! {"x": "y"};
389+
let val = d["x"].as_str().unwrap();
390+
assert_eq!(val, "y");
391+
392+
let d = doc! {"x": 1.9};
393+
let val = d["x"].as_f64().unwrap();
394+
assert_eq!(val, 1.9);
395+
396+
let d = doc! {"x": [1, 2, 3]};
397+
let val = d["x"].as_array().unwrap();
398+
assert_eq!(val.len(), 3);
399+
}
400+
401+
#[test]
402+
fn test_indexing_key_not_found() {
403+
let d = doc! {"x": 1};
404+
let val = &d["y"];
405+
assert!(val.as_null().is_some());
406+
407+
let d = doc! {"x": {"y": 1}};
408+
let val = &d["x"]["z"];
409+
assert!(val.as_null().is_some());
410+
}
411+
412+
#[test]
413+
fn test_indexing_on_wrong_bson_type() {
414+
let d = doc! {"x": {"y": 1}};
415+
let val = &d["x"]["y"]["z"];
416+
assert!(val.as_null().is_some());
417+
}

0 commit comments

Comments
 (0)