@@ -9,7 +9,11 @@ use crate::{
99 de:: MIN_BSON_DOCUMENT_SIZE ,
1010 error:: { Error , Result } ,
1111 raw:: { serde:: OwnedOrBorrowedRawDocument , RAW_DOCUMENT_NEWTYPE } ,
12+ Bson ,
1213 DateTime ,
14+ JavaScriptCodeWithScope ,
15+ RawBson ,
16+ RawJavaScriptCodeWithScope ,
1317 Timestamp ,
1418} ;
1519
@@ -508,6 +512,55 @@ impl RawDocument {
508512 let bytes = self . cstring_bytes_at ( start_at) ?;
509513 try_to_str ( bytes)
510514 }
515+
516+ /// Copy this into a [`Document`], returning an error if invalid BSON is encountered.
517+ pub fn to_document ( & self ) -> RawResult < Document > {
518+ self . try_into ( )
519+ }
520+
521+ /// Copy this into a [`Document`], returning an error if invalid BSON is encountered. Any
522+ /// invalid UTF-8 sequences will be replaced with the Unicode replacement character.
523+ pub fn to_document_utf8_lossy ( & self ) -> RawResult < Document > {
524+ let mut out = Document :: new ( ) ;
525+ for elem in self . iter_elements ( ) {
526+ let elem = elem?;
527+ let value = deep_utf8_lossy ( elem. value_utf8_lossy ( ) ?) ?;
528+ out. insert ( elem. key ( ) , value) ;
529+ }
530+ Ok ( out)
531+ }
532+ }
533+
534+ fn deep_utf8_lossy ( src : RawBson ) -> RawResult < Bson > {
535+ match src {
536+ RawBson :: Array ( arr) => {
537+ let mut tmp = vec ! [ ] ;
538+ for elem in arr. iter_elements ( ) {
539+ tmp. push ( deep_utf8_lossy ( elem?. value_utf8_lossy ( ) ?) ?) ;
540+ }
541+ Ok ( Bson :: Array ( tmp) )
542+ }
543+ RawBson :: Document ( doc) => {
544+ let mut tmp = doc ! { } ;
545+ for elem in doc. iter_elements ( ) {
546+ let elem = elem?;
547+ tmp. insert ( elem. key ( ) , deep_utf8_lossy ( elem. value_utf8_lossy ( ) ?) ?) ;
548+ }
549+ Ok ( Bson :: Document ( tmp) )
550+ }
551+ RawBson :: JavaScriptCodeWithScope ( RawJavaScriptCodeWithScope { code, scope } ) => {
552+ let mut tmp = doc ! { } ;
553+ for elem in scope. iter_elements ( ) {
554+ let elem = elem?;
555+ tmp. insert ( elem. key ( ) , deep_utf8_lossy ( elem. value_utf8_lossy ( ) ?) ?) ;
556+ }
557+ Ok ( Bson :: JavaScriptCodeWithScope ( JavaScriptCodeWithScope {
558+ code,
559+ scope : tmp,
560+ } ) )
561+ }
562+ v => v. try_into ( ) ,
563+ }
511564}
512565
513566impl < ' de : ' a , ' a > Deserialize < ' de > for & ' a RawDocument {
0 commit comments