diff --git a/serde-tests/test.rs b/serde-tests/test.rs index 85c62ace..49d68774 100644 --- a/serde-tests/test.rs +++ b/serde-tests/test.rs @@ -29,14 +29,6 @@ use bson::{ DeserializerOptions, Document, JavaScriptCodeWithScope, - RawArray, - RawBinary, - RawBson, - RawDbPointer, - RawDocument, - RawDocumentBuf, - RawJavaScriptCodeWithScope, - RawRegex, Regex, SerializerOptions, Timestamp, @@ -145,18 +137,6 @@ where ); } -/// Verifies the following: -/// - Deserializing a `T` from the provided bytes does not error -/// - Serializing the `T` back to bytes produces the input. -fn run_raw_round_trip_test<'de, T>(bytes: &'de [u8], description: &str) -where - T: Deserialize<'de> + Serialize + std::fmt::Debug, -{ - let t: T = bson::from_slice(bytes).expect(description); - let vec = bson::to_vec(&t).expect(description); - assert_eq!(vec.as_slice(), bytes); -} - #[test] fn smoke() { #[derive(Serialize, Deserialize, PartialEq, Debug)] @@ -727,154 +707,6 @@ fn empty_array() { run_deserialize_test(&v, &doc, "empty_array"); } -#[test] -fn raw_doc_buf() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo { - d: RawDocumentBuf, - } - - let bytes = bson::to_vec(&doc! { - "d": { - "a": 12, - "b": 5.5, - "c": [1, true, "ok"], - "d": { "a": "b" }, - "e": ObjectId::new(), - } - }) - .expect("raw_doc_buf"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_doc_buf"); -} - -#[test] -fn raw_doc() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - d: &'a RawDocument, - } - - let bytes = bson::to_vec(&doc! { - "d": { - "a": 12, - "b": 5.5, - "c": [1, true, "ok"], - "d": { "a": "b" }, - "e": ObjectId::new(), - } - }) - .expect("raw doc"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_doc"); -} - -#[test] -fn raw_array() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - d: &'a RawArray, - } - - let bytes = bson::to_vec(&doc! { - "d": [1, true, { "ok": 1 }, [ "sub", "array" ], Uuid::new()] - }) - .expect("raw_array"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_array"); -} - -#[test] -fn raw_binary() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - generic: RawBinary<'a>, - - #[serde(borrow)] - old: RawBinary<'a>, - - #[serde(borrow)] - uuid: RawBinary<'a>, - - #[serde(borrow)] - other: RawBinary<'a>, - } - - let bytes = bson::to_vec(&doc! { - "generic": Binary { - bytes: vec![1, 2, 3, 4, 5], - subtype: BinarySubtype::Generic, - }, - "old": Binary { - bytes: vec![1, 2, 3], - subtype: BinarySubtype::BinaryOld, - }, - "uuid": Uuid::new(), - "other": Binary { - bytes: vec![1u8; 100], - subtype: BinarySubtype::UserDefined(100), - } - }) - .expect("raw_binary"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_binary"); -} - -#[test] -fn raw_regex() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - r: RawRegex<'a>, - } - - let bytes = bson::to_vec(&doc! { - "r": Regex { - pattern: "a[b-c]d".to_string(), - options: "ab".to_string(), - }, - }) - .expect("raw_regex"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_regex"); -} - -#[test] -fn raw_code_w_scope() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - r: RawJavaScriptCodeWithScope<'a>, - } - - let bytes = bson::to_vec(&doc! { - "r": JavaScriptCodeWithScope { - code: "console.log(x)".to_string(), - scope: doc! { "x": 1 }, - }, - }) - .expect("raw_code_w_scope"); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_code_w_scope"); -} - -#[test] -fn raw_db_pointer() { - #[derive(Serialize, Deserialize, PartialEq, Debug)] - struct Foo<'a> { - #[serde(borrow)] - a: RawDbPointer<'a>, - } - - // From the "DBpointer" bson corpus test - let bytes = hex::decode("1A0000000C610002000000620056E1FC72E0C917E9C471416100").unwrap(); - - run_raw_round_trip_test::(bytes.as_slice(), "raw_db_pointer"); -} - #[derive(Debug, Deserialize, Serialize, PartialEq)] struct SubDoc { a: i32, @@ -1077,64 +909,6 @@ fn all_types_rmp() { assert_eq!(back, v); } -#[test] -fn all_raw_types_rmp() { - #[derive(Debug, Serialize, Deserialize, PartialEq)] - struct AllRawTypes<'a> { - #[serde(borrow)] - bson: RawBson<'a>, - #[serde(borrow)] - document: &'a RawDocument, - #[serde(borrow)] - array: &'a RawArray, - buf: RawDocumentBuf, - #[serde(borrow)] - binary: RawBinary<'a>, - #[serde(borrow)] - code_w_scope: RawJavaScriptCodeWithScope<'a>, - #[serde(borrow)] - regex: RawRegex<'a>, - } - - let doc_bytes = bson::to_vec(&doc! { - "bson": "some string", - "array": [1, 2, 3], - "binary": Binary { bytes: vec![1, 2, 3], subtype: BinarySubtype::Generic }, - "binary_old": Binary { bytes: vec![1, 2, 3], subtype: BinarySubtype::BinaryOld }, - "code_w_scope": JavaScriptCodeWithScope { - code: "ok".to_string(), - scope: doc! { "x": 1 }, - }, - "regex": Regex { - pattern: "pattern".to_string(), - options: "opt".to_string() - } - }) - .unwrap(); - let doc_buf = RawDocumentBuf::new(doc_bytes).unwrap(); - let document = &doc_buf; - let array = document.get_array("array").unwrap(); - - let v = AllRawTypes { - bson: document.get("bson").unwrap().unwrap(), - array, - document, - buf: doc_buf.clone(), - binary: document.get_binary("binary").unwrap(), - code_w_scope: document - .get("code_w_scope") - .unwrap() - .unwrap() - .as_javascript_with_scope() - .unwrap(), - regex: document.get_regex("regex").unwrap(), - }; - let serialized = rmp_serde::to_vec_named(&v).unwrap(); - let back: AllRawTypes = rmp_serde::from_slice(&serialized).unwrap(); - - assert_eq!(back, v); -} - #[test] fn borrowed() { #[derive(Debug, Deserialize, PartialEq)] @@ -1280,71 +1054,18 @@ fn serde_with_uuid() { run_test(&f, &expected, "serde_with - uuid"); } -#[test] -fn hint_cleared() { - #[derive(Debug, Serialize, Deserialize)] - struct Foo<'a> { - #[serde(borrow)] - doc: &'a RawDocument, - #[serde(borrow)] - binary: RawBinary<'a>, - } - - let binary_value = Binary { - bytes: vec![1, 2, 3, 4], - subtype: BinarySubtype::Generic, - }; - - let doc_value = doc! { - "binary": binary_value.clone() - }; - - let bytes = bson::to_vec(&doc_value).unwrap(); - - let doc = RawDocument::new(&bytes).unwrap(); - let binary = doc.get_binary("binary").unwrap(); - - let f = Foo { doc, binary }; - - let serialized_bytes = bson::to_vec(&f).unwrap(); - let round_doc: Document = bson::from_slice(&serialized_bytes).unwrap(); - - assert_eq!(round_doc, doc! { "doc": doc_value, "binary": binary_value }); -} - #[test] fn non_human_readable() { - let bytes = vec![1, 2, 3, 4]; - let binary = RawBinary { - bytes: &bytes, - subtype: BinarySubtype::BinaryOld, - }; - - let doc_bytes = bson::to_vec(&doc! { "a": "b", "array": [1, 2, 3] }).unwrap(); - let doc = RawDocument::new(doc_bytes.as_slice()).unwrap(); - let arr = doc.get_array("array").unwrap(); let oid = ObjectId::new(); let uuid = Uuid::new(); #[derive(Debug, Deserialize, Serialize)] - struct Foo<'a> { - #[serde(borrow)] - binary: RawBinary<'a>, - #[serde(borrow)] - doc: &'a RawDocument, - #[serde(borrow)] - arr: &'a RawArray, + struct Foo { oid: ObjectId, uuid: Uuid, } - let val = Foo { - binary, - doc, - arr, - oid, - uuid, - }; + let val = Foo { oid, uuid }; let human_readable = bson::to_bson(&val).unwrap(); let non_human_readable = bson::to_bson_with_options( @@ -1354,12 +1075,6 @@ fn non_human_readable() { .unwrap(); let expected = bson!({ - "binary": Binary { bytes: bytes.clone(), subtype: BinarySubtype::BinaryOld }, - "doc": { - "a": "b", - "array": [1, 2, 3], - }, - "arr": [1, 2, 3], "oid": oid, "uuid": uuid }); diff --git a/src/lib.rs b/src/lib.rs index 164b4456..7591a3ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -272,14 +272,11 @@ pub use self::{ bson::{Array, Binary, Bson, DbPointer, Document, JavaScriptCodeWithScope, Regex, Timestamp}, datetime::DateTime, de::{ - from_bson, from_bson_with_options, from_document, from_document_with_options, from_reader, from_reader_utf8_lossy, - from_slice, from_slice_utf8_lossy, Deserializer, DeserializerOptions, + from_bson, from_bson_with_options, from_document, from_document_with_options, from_reader, + from_reader_utf8_lossy, from_slice, from_slice_utf8_lossy, Deserializer, + DeserializerOptions, }, decimal128::Decimal128, - raw::{ - RawArray, RawBinary, RawBson, RawDbPointer, RawDocument, RawDocumentBuf, RawJavaScriptCodeWithScope, - RawRegex, - }, ser::{ to_bson, to_bson_with_options, to_document, to_document_with_options, to_vec, Serializer, SerializerOptions, @@ -287,6 +284,8 @@ pub use self::{ uuid::{Uuid, UuidRepresentation}, }; +pub(crate) use self::raw::RawDocument; + #[macro_use] mod macros; mod bson; @@ -296,7 +295,7 @@ pub mod decimal128; pub mod document; pub mod extjson; pub mod oid; -pub mod raw; +pub(crate) mod raw; pub mod ser; pub mod serde_helpers; pub mod spec; diff --git a/src/raw/array.rs b/src/raw/array.rs index 665c5632..d859f5c8 100644 --- a/src/raw/array.rs +++ b/src/raw/array.rs @@ -33,43 +33,10 @@ use crate::{ /// Iterating over a [`RawArray`] yields either an error or a value that borrows from the /// original document without making any additional allocations. /// -/// ``` -/// use bson::{doc, raw::RawDocument}; -/// -/// let doc = doc! { -/// "x": [1, true, "two", 5.5] -/// }; -/// let bytes = bson::to_vec(&doc)?; -/// -/// let rawdoc = RawDocument::new(bytes.as_slice())?; -/// let rawarray = rawdoc.get_array("x")?; -/// -/// for v in rawarray { -/// println!("{:?}", v?); -/// } -/// # Ok::<(), Box>(()) -/// ``` -/// /// Individual elements can be accessed using [`RawArray::get`] or any of /// the type-specific getters, such as [`RawArray::get_object_id`] or /// [`RawArray::get_str`]. Note that accessing elements is an O(N) operation, as it /// requires iterating through the array from the beginning to find the requested index. -/// -/// ``` -/// # use bson::raw::{ValueAccessError}; -/// use bson::{doc, raw::RawDocument}; -/// -/// let doc = doc! { -/// "x": [1, true, "two", 5.5] -/// }; -/// let bytes = bson::to_vec(&doc)?; -/// -/// let rawdoc = RawDocument::new(bytes.as_slice())?; -/// let rawarray = rawdoc.get_array("x")?; -/// -/// assert_eq!(rawarray.get_bool(1)?, true); -/// # Ok::<(), Box>(()) -/// ``` #[derive(PartialEq)] #[repr(transparent)] pub struct RawArray { diff --git a/src/raw/document.rs b/src/raw/document.rs index 34c1ef45..68b4a90c 100644 --- a/src/raw/document.rs +++ b/src/raw/document.rs @@ -39,31 +39,11 @@ use crate::{oid::ObjectId, spec::ElementType, Document}; /// /// Iterating over a [`RawDocument`] yields either an error or a key-value pair that borrows from /// the original document without making any additional allocations. -/// ``` -/// # use bson::raw::{Error}; -/// use bson::raw::RawDocument; -/// -/// let doc = RawDocument::new(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00")?; -/// let mut iter = doc.into_iter(); -/// let (key, value) = iter.next().unwrap()?; -/// assert_eq!(key, "hi"); -/// assert_eq!(value.as_str(), Some("y'all")); -/// assert!(iter.next().is_none()); -/// # Ok::<(), Error>(()) -/// ``` /// /// Individual elements can be accessed using [`RawDocument::get`] or any of /// the type-specific getters, such as [`RawDocument::get_object_id`] or /// [`RawDocument::get_str`]. Note that accessing elements is an O(N) operation, as it /// requires iterating through the document from the beginning to find the requested key. -/// -/// ``` -/// use bson::raw::RawDocument; -/// -/// let doc = RawDocument::new(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00")?; -/// assert_eq!(doc.get_str("hi")?, "y'all"); -/// # Ok::<(), Box>(()) -/// ``` #[derive(PartialEq)] #[repr(transparent)] pub struct RawDocument { @@ -82,13 +62,6 @@ impl RawDocument { /// BSON elements is _not_ validated at all by this method. If the /// bytes do not conform to the BSON spec, then method calls on /// the [`RawDocument`] will return Errors where appropriate. - /// - /// ``` - /// use bson::raw::RawDocument; - /// - /// let doc = RawDocument::new(b"\x05\0\0\0\0")?; - /// # Ok::<(), bson::raw::Error>(()) - /// ``` pub fn new + ?Sized>(data: &D) -> Result<&RawDocument> { let data = data.as_ref(); @@ -139,14 +112,6 @@ impl RawDocument { } /// Creates a new [`RawDocument`] with an owned copy of the BSON bytes. - /// - /// ``` - /// use bson::raw::{RawDocument, RawDocumentBuf, Error}; - /// - /// let data = b"\x05\0\0\0\0"; - /// let doc_ref = RawDocument::new(data)?; - /// let doc: RawDocumentBuf = doc_ref.to_raw_document_buf(); - /// # Ok::<(), Error>(()) pub fn to_raw_document_buf(&self) -> RawDocumentBuf { // unwrap is ok here because we already verified the bytes in `RawDocumentRef::new` RawDocumentBuf::new(self.data.to_owned()).unwrap() @@ -154,21 +119,6 @@ impl RawDocument { /// Gets a reference to the value corresponding to the given key by iterating until the key is /// found. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, oid::ObjectId, raw::{RawDocumentBuf, RawBson}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "_id": ObjectId::new(), - /// "f64": 2.5, - /// })?; - /// - /// let element = doc.get("f64")?.expect("finding key f64"); - /// assert_eq!(element.as_f64(), Some(2.5)); - /// assert!(doc.get("unknown")?.is_none()); - /// # Ok::<(), Error>(()) - /// ``` pub fn get(&self, key: impl AsRef) -> Result>> { for result in self.into_iter() { let (k, v) = result?; @@ -211,279 +161,77 @@ impl RawDocument { /// Gets a reference to the BSON double value corresponding to a given key or returns an error /// if the key corresponds to a value which isn't a double. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::raw::{ValueAccessErrorKind, RawDocumentBuf}; - /// use bson::doc; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "bool": true, - /// "f64": 2.5, - /// })?; - /// - /// assert_eq!(doc.get_f64("f64")?, 2.5); - /// assert!(matches!(doc.get_f64("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_f64("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_f64(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::Double, RawBson::as_f64) } /// Gets a reference to the string value corresponding to a given key or returns an error if the /// key corresponds to a value which isn't a string. - /// - /// ``` - /// use bson::{doc, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "string": "hello", - /// "bool": true, - /// })?; - /// - /// assert_eq!(doc.get_str("string")?, "hello"); - /// assert!(matches!(doc.get_str("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_str("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_str(&self, key: impl AsRef) -> ValueAccessResult<&'_ str> { self.get_with(key, ElementType::String, RawBson::as_str) } /// Gets a reference to the document value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't a document. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::{ValueAccessErrorKind, RawDocumentBuf}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "doc": { "key": "value"}, - /// "bool": true, - /// })?; - /// - /// assert_eq!(doc.get_document("doc")?.get_str("key")?, "value"); - /// assert!(matches!(doc.get_document("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_document("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_document(&self, key: impl AsRef) -> ValueAccessResult<&'_ RawDocument> { self.get_with(key, ElementType::EmbeddedDocument, RawBson::as_document) } /// Gets a reference to the array value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't an array. - /// - /// ``` - /// use bson::{doc, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "array": [true, 3], - /// "bool": true, - /// })?; - /// - /// let mut arr_iter = doc.get_array("array")?.into_iter(); - /// let _: bool = arr_iter.next().unwrap()?.as_bool().unwrap(); - /// let _: i32 = arr_iter.next().unwrap()?.as_i32().unwrap(); - /// - /// assert!(arr_iter.next().is_none()); - /// assert!(doc.get_array("bool").is_err()); - /// assert!(matches!(doc.get_array("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_array(&self, key: impl AsRef) -> ValueAccessResult<&'_ RawArray> { self.get_with(key, ElementType::Array, RawBson::as_array) } /// Gets a reference to the BSON binary value corresponding to a given key or returns an error /// if the key corresponds to a value which isn't a binary value. - /// - /// ``` - /// use bson::{ - /// doc, - /// raw::{ValueAccessErrorKind, RawDocumentBuf, RawBinary}, - /// spec::BinarySubtype, - /// Binary, - /// }; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "binary": Binary { subtype: BinarySubtype::Generic, bytes: vec![1, 2, 3] }, - /// "bool": true, - /// })?; - /// - /// assert_eq!(&doc.get_binary("binary")?.bytes, &[1, 2, 3]); - /// assert!(matches!(doc.get_binary("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_binary("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_binary(&self, key: impl AsRef) -> ValueAccessResult> { self.get_with(key, ElementType::Binary, RawBson::as_binary) } /// Gets a reference to the ObjectId value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't an ObjectId. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, oid::ObjectId, raw::{ValueAccessErrorKind, RawDocumentBuf}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "_id": ObjectId::new(), - /// "bool": true, - /// })?; - /// - /// let oid = doc.get_object_id("_id")?; - /// assert!(matches!(doc.get_object_id("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_object_id("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_object_id(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::ObjectId, RawBson::as_object_id) } /// Gets a reference to the boolean value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't a boolean. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, oid::ObjectId, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "_id": ObjectId::new(), - /// "bool": true, - /// })?; - /// - /// assert!(doc.get_bool("bool")?); - /// assert!(matches!(doc.get_bool("_id").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_bool("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_bool(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::Boolean, RawBson::as_bool) } /// Gets a reference to the BSON DateTime value corresponding to a given key or returns an /// error if the key corresponds to a value which isn't a DateTime. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::{ValueAccessErrorKind, RawDocumentBuf}, DateTime}; - /// - /// let dt = DateTime::now(); - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "created_at": dt, - /// "bool": true, - /// })?; - /// - /// assert_eq!(doc.get_datetime("created_at")?, dt); - /// assert!(matches!(doc.get_datetime("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_datetime("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_datetime(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::DateTime, RawBson::as_datetime) } /// Gets a reference to the BSON regex value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't a regex. - /// - /// ``` - /// use bson::{doc, Regex, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "regex": Regex { - /// pattern: r"end\s*$".into(), - /// options: "i".into(), - /// }, - /// "bool": true, - /// })?; - /// - /// assert_eq!(doc.get_regex("regex")?.pattern(), r"end\s*$"); - /// assert_eq!(doc.get_regex("regex")?.options(), "i"); - /// assert!(matches!(doc.get_regex("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_regex("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_regex(&self, key: impl AsRef) -> ValueAccessResult> { self.get_with(key, ElementType::RegularExpression, RawBson::as_regex) } /// Gets a reference to the BSON timestamp value corresponding to a given key or returns an /// error if the key corresponds to a value which isn't a timestamp. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, Timestamp, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "bool": true, - /// "ts": Timestamp { time: 649876543, increment: 9 }, - /// })?; - /// - /// let timestamp = doc.get_timestamp("ts")?; - /// - /// assert_eq!(timestamp.time, 649876543); - /// assert_eq!(timestamp.increment, 9); - /// assert!(matches!(doc.get_timestamp("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_timestamp("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_timestamp(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::Timestamp, RawBson::as_timestamp) } /// Gets a reference to the BSON int32 value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't a 32-bit integer. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::{RawDocumentBuf, ValueAccessErrorKind}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "bool": true, - /// "i32": 1_000_000, - /// })?; - /// - /// assert_eq!(doc.get_i32("i32")?, 1_000_000); - /// assert!(matches!(doc.get_i32("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { ..})); - /// assert!(matches!(doc.get_i32("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_i32(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::Int32, RawBson::as_i32) } /// Gets a reference to the BSON int64 value corresponding to a given key or returns an error if /// the key corresponds to a value which isn't a 64-bit integer. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::{ValueAccessErrorKind, RawDocumentBuf}}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { - /// "bool": true, - /// "i64": 9223372036854775807_i64, - /// })?; - /// - /// assert_eq!(doc.get_i64("i64")?, 9223372036854775807); - /// assert!(matches!(doc.get_i64("bool").unwrap_err().kind, ValueAccessErrorKind::UnexpectedType { .. })); - /// assert!(matches!(doc.get_i64("unknown").unwrap_err().kind, ValueAccessErrorKind::NotPresent)); - /// # Ok::<(), Box>(()) - /// ``` pub fn get_i64(&self, key: impl AsRef) -> ValueAccessResult { self.get_with(key, ElementType::Int64, RawBson::as_i64) } /// Return a reference to the contained data as a `&[u8]` - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::RawDocumentBuf}; - /// let docbuf = RawDocumentBuf::from_document(&doc!{})?; - /// assert_eq!(docbuf.as_bytes(), b"\x05\x00\x00\x00\x00"); - /// # Ok::<(), Error>(()) - /// ``` pub fn as_bytes(&self) -> &[u8] { &self.data } diff --git a/src/raw/document_buf.rs b/src/raw/document_buf.rs index f1c216d3..a69b91cb 100644 --- a/src/raw/document_buf.rs +++ b/src/raw/document_buf.rs @@ -20,32 +20,11 @@ use super::{Error, ErrorKind, Iter, RawBson, RawDocument, Result}; /// Iterating over a [`RawDocumentBuf`] yields either an error or a key-value pair that borrows from /// the original document without making any additional allocations. /// -/// ``` -/// # use bson::raw::Error; -/// use bson::raw::RawDocumentBuf; -/// -/// let doc = RawDocumentBuf::new(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00".to_vec())?; -/// let mut iter = doc.iter(); -/// let (key, value) = iter.next().unwrap()?; -/// assert_eq!(key, "hi"); -/// assert_eq!(value.as_str(), Some("y'all")); -/// assert!(iter.next().is_none()); -/// # Ok::<(), Error>(()) -/// ``` -/// /// This type implements `Deref` to [`RawDocument`], meaning that all methods on [`RawDocument`] are /// available on [`RawDocumentBuf`] values as well. This includes [`RawDocument::get`] or any of the /// type-specific getters, such as [`RawDocument::get_object_id`] or [`RawDocument::get_str`]. Note /// that accessing elements is an O(N) operation, as it requires iterating through the document from /// the beginning to find the requested key. -/// -/// ``` -/// use bson::raw::RawDocumentBuf; -/// -/// let doc = RawDocumentBuf::new(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00".to_vec())?; -/// assert_eq!(doc.get_str("hi")?, "y'all"); -/// # Ok::<(), Box>(()) -/// ``` #[derive(Clone, PartialEq)] pub struct RawDocumentBuf { data: Vec, @@ -63,31 +42,12 @@ impl RawDocumentBuf { /// BSON elements is _not_ validated at all by this method. If the /// bytes do not conform to the BSON spec, then method calls on /// the RawDocument will return Errors where appropriate. - /// - /// ``` - /// # use bson::raw::{RawDocumentBuf, Error}; - /// let doc = RawDocumentBuf::new(b"\x05\0\0\0\0".to_vec())?; - /// # Ok::<(), Error>(()) - /// ``` pub fn new(data: Vec) -> Result { let _ = RawDocument::new(data.as_slice())?; Ok(Self { data }) } /// Create a [`RawDocumentBuf`] from a [`Document`]. - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, oid::ObjectId, raw::RawDocumentBuf}; - /// - /// let document = doc! { - /// "_id": ObjectId::new(), - /// "name": "Herman Melville", - /// "title": "Moby-Dick", - /// }; - /// let doc = RawDocumentBuf::from_document(&document)?; - /// # Ok::<(), Error>(()) - /// ``` pub fn from_document(doc: &Document) -> Result { let mut data = Vec::new(); doc.to_writer(&mut data).map_err(|e| Error { @@ -103,20 +63,6 @@ impl RawDocumentBuf { /// Gets an iterator over the elements in the [`RawDocumentBuf`], which yields /// `Result<(&str, RawBson<'_>)>`. /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::RawDocumentBuf}; - /// - /// let doc = RawDocumentBuf::from_document(&doc! { "ferris": true })?; - /// - /// for element in doc.iter() { - /// let (key, value) = element?; - /// assert_eq!(key, "ferris"); - /// assert_eq!(value.as_bool(), Some(true)); - /// } - /// # Ok::<(), Error>(()) - /// ``` - /// /// # Note: /// /// There is no owning iterator for [`RawDocumentBuf`]. If you need ownership over @@ -127,15 +73,6 @@ impl RawDocumentBuf { } /// Return the contained data as a `Vec` - /// - /// ``` - /// # use bson::raw::Error; - /// use bson::{doc, raw::RawDocumentBuf}; - /// - /// let doc = RawDocumentBuf::from_document(&doc!{})?; - /// assert_eq!(doc.into_vec(), b"\x05\x00\x00\x00\x00".to_vec()); - /// # Ok::<(), Error>(()) - /// ``` pub fn into_vec(self) -> Vec { self.data } diff --git a/src/raw/mod.rs b/src/raw/mod.rs index 89c16ea1..0ce10384 100644 --- a/src/raw/mod.rs +++ b/src/raw/mod.rs @@ -16,53 +16,12 @@ //! implementation) returns a `Result`, since the bytes contained in the document are not fully //! validated until trying to access the contained data. //! -//! ```rust -//! use bson::raw::{ -//! RawBson, -//! RawDocumentBuf, -//! }; -//! -//! // See http://bsonspec.org/spec.html for details on the binary encoding of BSON. -//! let doc = RawDocumentBuf::new(b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00".to_vec())?; -//! let elem = doc.get("hi")?.unwrap(); -//! -//! assert_eq!( -//! elem.as_str(), -//! Some("y'all"), -//! ); -//! # Ok::<(), bson::raw::Error>(()) -//! ``` -//! //! ### [`crate::Document`] interop //! //! A [`RawDocument`] can be created from a [`crate::Document`]. Internally, this //! serializes the [`crate::Document`] to a `Vec`, and then includes those bytes in the //! [`RawDocument`]. //! -//! ```rust -//! use bson::{ -//! raw::RawDocumentBuf, -//! doc, -//! }; -//! -//! let document = doc! { -//! "goodbye": { -//! "cruel": "world" -//! } -//! }; -//! -//! let raw = RawDocumentBuf::from_document(&document)?; -//! let value = raw -//! .get_document("goodbye")? -//! .get_str("cruel")?; -//! -//! assert_eq!( -//! value, -//! "world", -//! ); -//! # Ok::<(), Box>(()) -//! ``` -//! //! ### Reference type ([`RawDocument`]) //! //! A BSON document can also be accessed with the [`RawDocument`] type, which is an @@ -72,46 +31,12 @@ //! //! The below example constructs a bson document in a stack-based array, //! and extracts a `&str` from it, performing no heap allocation. -//! ```rust -//! use bson::raw::RawDocument; -//! -//! let bytes = b"\x13\x00\x00\x00\x02hi\x00\x06\x00\x00\x00y'all\x00\x00"; -//! assert_eq!(RawDocument::new(bytes)?.get_str("hi")?, "y'all"); -//! # Ok::<(), Box>(()) -//! ``` //! //! ### Iteration //! //! [`RawDocument`] implements [`IntoIterator`](std::iter::IntoIterator), which can also be //! accessed via [`RawDocumentBuf::iter`]. -//! ```rust -//! use bson::{ -//! raw::{ -//! RawBson, -//! RawDocumentBuf, -//! }, -//! doc, -//! }; -//! -//! let original_doc = doc! { -//! "crate": "bson", -//! "year": "2021", -//! }; -//! -//! let doc = RawDocumentBuf::from_document(&original_doc)?; -//! let mut doc_iter = doc.iter(); -//! -//! let (key, value): (&str, RawBson) = doc_iter.next().unwrap()?; -//! assert_eq!(key, "crate"); -//! assert_eq!(value.as_str(), Some("bson")); -//! -//! let (key, value): (&str, RawBson) = doc_iter.next().unwrap()?; -//! assert_eq!(key, "year"); -//! assert_eq!(value.as_str(), Some("2021")); -//! # Ok::<(), bson::raw::Error>(()) -//! ``` - mod array; mod bson; mod document;