@@ -189,43 +189,38 @@ impl RawDocumentBuf {
189
189
///
190
190
/// If the provided key contains an interior null byte, this method will panic.
191
191
///
192
+ /// Values can be any type that can be converted to either borrowed or owned raw bson data; see
193
+ /// the documentation for [BindRawBsonRef] for more details.
192
194
/// ```
193
195
/// # use bson::raw::Error;
194
- /// use bson::{doc, raw::RawDocumentBuf};
196
+ /// use bson::{doc, raw::{RawBsonRef, RawDocumentBuf} };
195
197
///
196
198
/// let mut doc = RawDocumentBuf::new();
199
+ /// // `&str` and `i32` both convert to `RawBsonRef`
197
200
/// doc.append("a string", "some string");
198
201
/// doc.append("an integer", 12_i32);
199
202
///
200
203
/// let mut subdoc = RawDocumentBuf::new();
201
204
/// subdoc.append("a key", true);
202
- /// doc.append("a document", subdoc);
205
+ /// doc.append("a borrowed document", &subdoc);
206
+ /// doc.append("an owned document", subdoc);
203
207
///
204
208
/// let expected = doc! {
205
209
/// "a string": "some string",
206
210
/// "an integer": 12_i32,
207
- /// "a document": { "a key": true },
211
+ /// "a borrowed document": { "a key": true },
212
+ /// "an owned document": { "a key": true },
208
213
/// };
209
214
///
210
215
/// assert_eq!(doc.to_document()?, expected);
211
216
/// # Ok::<(), Error>(())
212
217
/// ```
213
- pub fn append ( & mut self , key : impl AsRef < str > , value : impl Into < RawBson > ) {
214
- let value = value. into ( ) ;
215
- self . append_ref ( key, value. as_raw_bson_ref ( ) )
216
- }
217
-
218
- /// Append a key value pair to the end of the document without checking to see if
219
- /// the key already exists.
220
- ///
221
- /// It is a user error to append the same key more than once to the same document, and it may
222
- /// result in errors when communicating with MongoDB.
223
- ///
224
- /// If the provided key contains an interior null byte, this method will panic.
225
- pub fn append_ref < ' a > ( & mut self , key : impl AsRef < str > , value : impl Into < RawBsonRef < ' a > > ) {
226
- raw_writer:: RawWriter :: new ( & mut self . data )
227
- . append ( key. as_ref ( ) , value. into ( ) )
228
- . expect ( "key should not contain interior null byte" )
218
+ pub fn append ( & mut self , key : impl AsRef < str > , value : impl BindRawBsonRef ) {
219
+ value. bind ( |value_ref| {
220
+ raw_writer:: RawWriter :: new ( & mut self . data )
221
+ . append ( key. as_ref ( ) , value_ref)
222
+ . expect ( "key should not contain interior null byte" )
223
+ } )
229
224
}
230
225
231
226
/// Convert this [`RawDocumentBuf`] to a [`Document`], returning an error
@@ -325,7 +320,7 @@ impl Borrow<RawDocument> for RawDocumentBuf {
325
320
}
326
321
}
327
322
328
- impl < S : AsRef < str > , T : Into < RawBson > > FromIterator < ( S , T ) > for RawDocumentBuf {
323
+ impl < S : AsRef < str > , T : BindRawBsonRef > FromIterator < ( S , T ) > for RawDocumentBuf {
329
324
fn from_iter < I : IntoIterator < Item = ( S , T ) > > ( iter : I ) -> Self {
330
325
let mut buf = RawDocumentBuf :: new ( ) ;
331
326
for ( k, v) in iter {
@@ -334,3 +329,68 @@ impl<S: AsRef<str>, T: Into<RawBson>> FromIterator<(S, T)> for RawDocumentBuf {
334
329
buf
335
330
}
336
331
}
332
+
333
+ /// Types that can be consumed to produce raw bson references valid for a limited lifetime.
334
+ /// Conceptually a union between `T: Into<RawBson>` and `T: Into<RawBsonRef>`; if your type
335
+ /// implements `Into<RawBsonRef>` it will automatically implement this, but if it only
336
+ /// implements `Into<RawBson>` it will need to manually define the trivial impl.
337
+ pub trait BindRawBsonRef {
338
+ fn bind < F , R > ( self , f : F ) -> R
339
+ where
340
+ F : for < ' a > FnOnce ( RawBsonRef < ' a > ) -> R ;
341
+ }
342
+
343
+ impl < ' a , T : Into < RawBsonRef < ' a > > > BindRawBsonRef for T {
344
+ fn bind < F , R > ( self , f : F ) -> R
345
+ where
346
+ F : for < ' b > FnOnce ( RawBsonRef < ' b > ) -> R ,
347
+ {
348
+ f ( self . into ( ) )
349
+ }
350
+ }
351
+
352
+ impl BindRawBsonRef for RawBson {
353
+ fn bind < F , R > ( self , f : F ) -> R
354
+ where
355
+ F : for < ' a > FnOnce ( RawBsonRef < ' a > ) -> R ,
356
+ {
357
+ f ( self . as_raw_bson_ref ( ) )
358
+ }
359
+ }
360
+
361
+ impl BindRawBsonRef for & RawBson {
362
+ fn bind < F , R > ( self , f : F ) -> R
363
+ where
364
+ F : for < ' a > FnOnce ( RawBsonRef < ' a > ) -> R ,
365
+ {
366
+ f ( self . as_raw_bson_ref ( ) )
367
+ }
368
+ }
369
+
370
+ macro_rules! raw_bson_from_impls {
371
+ ( $( $t: ty) ,+$( , ) ?) => {
372
+ $(
373
+ impl BindRawBsonRef for $t {
374
+ fn bind<F , R >( self , f: F ) -> R
375
+ where
376
+ F : for <' a> FnOnce ( RawBsonRef <' a>) -> R ,
377
+ {
378
+ let tmp: RawBson = self . into( ) ;
379
+ f( tmp. as_raw_bson_ref( ) )
380
+ }
381
+ }
382
+ ) +
383
+ } ;
384
+ }
385
+
386
+ raw_bson_from_impls ! {
387
+ & crate :: binary:: Vector ,
388
+ crate :: Binary ,
389
+ crate :: DbPointer ,
390
+ super :: RawArrayBuf ,
391
+ RawDocumentBuf ,
392
+ super :: RawJavaScriptCodeWithScope ,
393
+ crate :: Regex ,
394
+ String ,
395
+ crate :: binary:: Vector ,
396
+ }
0 commit comments