Skip to content

Commit a0984fa

Browse files
RUST-429 Move encode_document/decode_document to Document namespace (#175)
1 parent d1d8e53 commit a0984fa

File tree

10 files changed

+135
-133
lines changed

10 files changed

+135
-133
lines changed

examples/decode.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use std::fs::File;
22

3+
use bson::Document;
4+
35
fn main() {
46
let mut f = File::open("examples/test.bson").unwrap();
57

6-
while let Ok(decoded) = bson::decode_document(&mut f) {
8+
while let Ok(decoded) = Document::decode(&mut f) {
79
println!("{:?}", decoded);
810
}
911
}

examples/encode.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::io::Cursor;
22

3-
use bson::{decode_document, encode_document, oid, Array, Bson, Document};
3+
use bson::{oid, Array, Bson, Document};
44

55
fn main() {
66
let mut doc = Document::new();
@@ -16,10 +16,10 @@ fn main() {
1616
doc.insert("array".to_string(), Bson::Array(arr));
1717

1818
let mut buf = Vec::new();
19-
encode_document(&mut buf, &doc).unwrap();
19+
doc.encode(&mut buf).unwrap();
2020

2121
println!("Encoded: {:?}", buf);
2222

23-
let doc = decode_document(&mut Cursor::new(&buf[..])).unwrap();
23+
let doc = Document::decode(&mut Cursor::new(&buf[..])).unwrap();
2424
println!("Decoded: {:?}", doc);
2525
}

fuzz/fuzz_targets/decode.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
#[macro_use] extern crate libfuzzer_sys;
33
extern crate bson;
44

5-
use bson::decode_document;
5+
use bson::Document;
66
use std::io::Cursor;
77

88
fuzz_target!(|buf: &[u8]| {
9-
let _ = decode_document(&mut Cursor::new(&buf[..]));
9+
let _ = Document::decode(&mut Cursor::new(&buf[..]));
1010
});

src/decoder/mod.rs

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fn read_cstring<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<String> {
8989
}
9090

9191
#[inline]
92-
fn read_i32<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<i32> {
92+
pub(crate) fn read_i32<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<i32> {
9393
reader.read_i32::<LittleEndian>().map_err(From::from)
9494
}
9595

@@ -109,27 +109,6 @@ fn read_f128<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Decimal128> {
109109
Ok(val)
110110
}
111111

112-
/// Attempt to decode a `Document` from a byte stream.
113-
pub fn decode_document<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Document> {
114-
let mut doc = Document::new();
115-
116-
// disregard the length: using Read::take causes infinite type recursion
117-
read_i32(reader)?;
118-
119-
loop {
120-
let tag = reader.read_u8()?;
121-
122-
if tag == 0 {
123-
break;
124-
}
125-
126-
let (key, val) = decode_bson_kvp(reader, tag, false)?;
127-
doc.insert(key, val);
128-
}
129-
130-
Ok(doc)
131-
}
132-
133112
fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderResult<Array> {
134113
let mut arr = Array::new();
135114

@@ -149,7 +128,7 @@ fn decode_array<R: Read + ?Sized>(reader: &mut R, utf8_lossy: bool) -> DecoderRe
149128
Ok(arr)
150129
}
151130

152-
fn decode_bson_kvp<R: Read + ?Sized>(
131+
pub(crate) fn decode_bson_kvp<R: Read + ?Sized>(
153132
reader: &mut R,
154133
tag: u8,
155134
utf8_lossy: bool,
@@ -160,7 +139,7 @@ fn decode_bson_kvp<R: Read + ?Sized>(
160139
let val = match ElementType::from(tag) {
161140
Some(ElementType::FloatingPoint) => Bson::FloatingPoint(reader.read_f64::<LittleEndian>()?),
162141
Some(ElementType::Utf8String) => read_string(reader, utf8_lossy).map(Bson::String)?,
163-
Some(ElementType::EmbeddedDocument) => decode_document(reader).map(Bson::Document)?,
142+
Some(ElementType::EmbeddedDocument) => Document::decode(reader).map(Bson::Document)?,
164143
Some(ElementType::Array) => decode_array(reader, utf8_lossy).map(Bson::Array)?,
165144
Some(ElementType::Binary) => {
166145
let mut len = read_i32(reader)?;
@@ -212,7 +191,7 @@ fn decode_bson_kvp<R: Read + ?Sized>(
212191
read_i32(reader)?;
213192

214193
let code = read_string(reader, utf8_lossy)?;
215-
let scope = decode_document(reader)?;
194+
let scope = Document::decode(reader)?;
216195
Bson::JavaScriptCodeWithScope(JavaScriptCodeWithScope { code, scope })
217196
}
218197
Some(ElementType::Integer32Bit) => read_i32(reader).map(Bson::I32)?,

src/document.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
use std::{
44
error,
55
fmt::{self, Debug, Display, Formatter},
6-
iter::{Extend, FromIterator, Map},
6+
io::{Read, Write},
7+
iter::{Extend, FromIterator, IntoIterator, Map},
78
marker::PhantomData,
9+
mem,
810
};
911

12+
use byteorder::{ReadBytesExt, WriteBytesExt};
13+
1014
use chrono::{DateTime, Utc};
1115

1216
use linked_hash_map::{self, LinkedHashMap};
@@ -17,6 +21,8 @@ use serde::de::{self, MapAccess, Visitor};
1721
use crate::decimal128::Decimal128;
1822
use crate::{
1923
bson::{Array, Binary, Bson, TimeStamp},
24+
decoder::{decode_bson_kvp, read_i32, DecoderResult},
25+
encoder::{encode_bson, write_i32, EncoderResult},
2026
oid::ObjectId,
2127
spec::BinarySubtype,
2228
};
@@ -503,6 +509,43 @@ impl Document {
503509
inner: self.inner.entry(k),
504510
}
505511
}
512+
513+
/// Attempts to encode the `Document` into a byte stream.
514+
pub fn encode<W: Write + ?Sized>(&self, writer: &mut W) -> EncoderResult<()> {
515+
let mut buf = Vec::new();
516+
for (key, val) in self.into_iter() {
517+
encode_bson(&mut buf, key.as_ref(), val)?;
518+
}
519+
520+
write_i32(
521+
writer,
522+
(buf.len() + mem::size_of::<i32>() + mem::size_of::<u8>()) as i32,
523+
)?;
524+
writer.write_all(&buf)?;
525+
writer.write_u8(0)?;
526+
Ok(())
527+
}
528+
529+
/// Attempts to decode a `Document` from a byte stream.
530+
pub fn decode<R: Read + ?Sized>(reader: &mut R) -> DecoderResult<Document> {
531+
let mut doc = Document::new();
532+
533+
// disregard the length: using Read::take causes infinite type recursion
534+
read_i32(reader)?;
535+
536+
loop {
537+
let tag = reader.read_u8()?;
538+
539+
if tag == 0 {
540+
break;
541+
}
542+
543+
let (key, val) = decode_bson_kvp(reader, tag, false)?;
544+
doc.insert(key, val);
545+
}
546+
547+
Ok(doc)
548+
}
506549
}
507550

508551
pub struct Entry<'a> {

src/encoder/mod.rs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use self::{
2929
serde::Encoder,
3030
};
3131

32-
use std::{io::Write, iter::IntoIterator, mem};
32+
use std::{io::Write, mem};
3333

3434
use byteorder::{LittleEndian, WriteBytesExt};
3535
use chrono::Timelike;
@@ -56,7 +56,7 @@ fn write_cstring<W: Write + ?Sized>(writer: &mut W, s: &str) -> EncoderResult<()
5656
}
5757

5858
#[inline]
59-
fn write_i32<W: Write + ?Sized>(writer: &mut W, val: i32) -> EncoderResult<()> {
59+
pub(crate) fn write_i32<W: Write + ?Sized>(writer: &mut W, val: i32) -> EncoderResult<()> {
6060
writer.write_i32::<LittleEndian>(val).map_err(From::from)
6161
}
6262

@@ -92,42 +92,19 @@ fn encode_array<W: Write + ?Sized>(writer: &mut W, arr: &[Bson]) -> EncoderResul
9292
Ok(())
9393
}
9494

95-
/// Attempt to encode a `Document` into a byte stream.
96-
///
97-
/// Can encode any type which is iterable as `(key: &str, value: &Bson)` pairs,
98-
/// which generally means most maps.
99-
pub fn encode_document<
100-
'a,
101-
S: AsRef<str> + 'a,
102-
W: Write + ?Sized,
103-
D: IntoIterator<Item = (&'a S, &'a Bson)>,
104-
>(
95+
pub(crate) fn encode_bson<W: Write + ?Sized>(
10596
writer: &mut W,
106-
doc: D,
97+
key: &str,
98+
val: &Bson,
10799
) -> EncoderResult<()> {
108-
let mut buf = Vec::new();
109-
for (key, val) in doc.into_iter() {
110-
encode_bson(&mut buf, key.as_ref(), val)?;
111-
}
112-
113-
write_i32(
114-
writer,
115-
(buf.len() + mem::size_of::<i32>() + mem::size_of::<u8>()) as i32,
116-
)?;
117-
writer.write_all(&buf)?;
118-
writer.write_u8(0)?;
119-
Ok(())
120-
}
121-
122-
fn encode_bson<W: Write + ?Sized>(writer: &mut W, key: &str, val: &Bson) -> EncoderResult<()> {
123100
writer.write_u8(val.element_type() as u8)?;
124101
write_cstring(writer, key)?;
125102

126103
match *val {
127104
Bson::FloatingPoint(v) => write_f64(writer, v),
128105
Bson::String(ref v) => write_string(writer, &v),
129106
Bson::Array(ref v) => encode_array(writer, &v),
130-
Bson::Document(ref v) => encode_document(writer, v),
107+
Bson::Document(ref v) => v.encode(writer),
131108
Bson::Boolean(v) => writer
132109
.write_u8(if v { 0x01 } else { 0x00 })
133110
.map_err(From::from),
@@ -146,7 +123,7 @@ fn encode_bson<W: Write + ?Sized>(writer: &mut W, key: &str, val: &Bson) -> Enco
146123
}) => {
147124
let mut buf = Vec::new();
148125
write_string(&mut buf, code)?;
149-
encode_document(&mut buf, scope)?;
126+
scope.encode(&mut buf)?;
150127

151128
write_i32(writer, buf.len() as i32 + 4)?;
152129
writer.write_all(&buf).map_err(From::from)

src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@
2727
//! ## Basic usage
2828
//!
2929
//! ```rust
30-
//! use bson::{decode_document, encode_document, Bson, Document};
30+
//! use bson::{Bson, Document};
3131
//! use std::io::Cursor;
3232
//!
3333
//! let mut doc = Document::new();
3434
//! doc.insert("foo".to_owned(), Bson::String("bar".to_owned()));
3535
//!
3636
//! let mut buf = Vec::new();
37-
//! encode_document(&mut buf, &doc).unwrap();
37+
//! doc.encode(&mut buf).unwrap();
3838
//!
39-
//! let doc = decode_document(&mut Cursor::new(&buf[..])).unwrap();
39+
//! let doc = Document::decode(&mut Cursor::new(&buf[..])).unwrap();
4040
//! ```
4141
4242
#![allow(clippy::cognitive_complexity)]
@@ -55,9 +55,9 @@ pub use self::{
5555
TimeStamp,
5656
UtcDateTime,
5757
},
58-
decoder::{decode_document, from_bson, Decoder, DecoderError, DecoderResult},
58+
decoder::{from_bson, Decoder, DecoderError, DecoderResult},
5959
document::{ValueAccessError, ValueAccessResult},
60-
encoder::{encode_document, to_bson, Encoder, EncoderError, EncoderResult},
60+
encoder::{to_bson, Encoder, EncoderError, EncoderResult},
6161
};
6262

6363
#[macro_use]

0 commit comments

Comments
 (0)