@@ -4,15 +4,14 @@ use std::{
4
4
error,
5
5
fmt:: { self , Debug , Display , Formatter } ,
6
6
io:: { Read , Write } ,
7
- iter:: { Extend , FromIterator , IntoIterator , Map } ,
7
+ iter:: { Extend , FromIterator , IntoIterator } ,
8
8
marker:: PhantomData ,
9
9
mem,
10
10
} ;
11
11
12
+ use ahash:: RandomState ;
12
13
use chrono:: { DateTime , Utc } ;
13
-
14
- use linked_hash_map:: { self , LinkedHashMap } ;
15
-
14
+ use indexmap:: IndexMap ;
16
15
use serde:: de:: { self , Error , MapAccess , Visitor } ;
17
16
18
17
#[ cfg( feature = "decimal128" ) ]
@@ -64,7 +63,7 @@ impl error::Error for ValueAccessError {}
64
63
/// A BSON document represented as an associative HashMap with insertion ordering.
65
64
#[ derive( Clone , PartialEq ) ]
66
65
pub struct Document {
67
- inner : LinkedHashMap < String , Bson > ,
66
+ inner : IndexMap < String , Bson , RandomState > ,
68
67
}
69
68
70
69
impl Default for Document {
@@ -101,24 +100,22 @@ impl Debug for Document {
101
100
102
101
/// An iterator over Document entries.
103
102
pub struct DocumentIntoIterator {
104
- inner : LinkedHashMap < String , Bson > ,
103
+ inner : indexmap :: map :: IntoIter < String , Bson > ,
105
104
}
106
105
107
106
/// An owning iterator over Document entries.
108
107
pub struct DocumentIterator < ' a > {
109
- inner : linked_hash_map :: Iter < ' a , String , Bson > ,
108
+ inner : indexmap :: map :: Iter < ' a , String , Bson > ,
110
109
}
111
110
112
- type DocumentMap < ' a , T > = Map < DocumentIterator < ' a > , fn ( ( & ' a String , & ' a Bson ) ) -> T > ;
113
-
114
111
/// An iterator over an Document's keys.
115
112
pub struct Keys < ' a > {
116
- inner : DocumentMap < ' a , & ' a String > ,
113
+ inner : indexmap :: map :: Keys < ' a , String , Bson > ,
117
114
}
118
115
119
116
/// An iterator over an Document's values.
120
117
pub struct Values < ' a > {
121
- inner : DocumentMap < ' a , & ' a Bson > ,
118
+ inner : indexmap :: map :: Values < ' a , String , Bson > ,
122
119
}
123
120
124
121
impl < ' a > Iterator for Keys < ' a > {
@@ -142,7 +139,9 @@ impl IntoIterator for Document {
142
139
type IntoIter = DocumentIntoIterator ;
143
140
144
141
fn into_iter ( self ) -> Self :: IntoIter {
145
- DocumentIntoIterator { inner : self . inner }
142
+ DocumentIntoIterator {
143
+ inner : self . inner . into_iter ( ) ,
144
+ }
146
145
}
147
146
}
148
147
@@ -171,7 +170,7 @@ impl<'a> Iterator for DocumentIntoIterator {
171
170
type Item = ( String , Bson ) ;
172
171
173
172
fn next ( & mut self ) -> Option < ( String , Bson ) > {
174
- self . inner . pop_front ( )
173
+ self . inner . next ( )
175
174
}
176
175
}
177
176
@@ -187,7 +186,7 @@ impl Document {
187
186
/// Creates a new empty Document.
188
187
pub fn new ( ) -> Document {
189
188
Document {
190
- inner : LinkedHashMap :: new ( ) ,
189
+ inner : IndexMap :: default ( ) ,
191
190
}
192
191
}
193
192
@@ -457,26 +456,16 @@ impl Document {
457
456
}
458
457
459
458
/// Gets a collection of all keys in the document.
460
- pub fn keys < ' a > ( & ' a self ) -> Keys < ' a > {
461
- fn first < A , B > ( ( a, _) : ( A , B ) ) -> A {
462
- a
463
- }
464
- let first: fn ( ( & ' a String , & ' a Bson ) ) -> & ' a String = first;
465
-
459
+ pub fn keys ( & self ) -> Keys {
466
460
Keys {
467
- inner : self . iter ( ) . map ( first ) ,
461
+ inner : self . inner . keys ( ) ,
468
462
}
469
463
}
470
464
471
465
/// Gets a collection of all values in the document.
472
- pub fn values < ' a > ( & ' a self ) -> Values < ' a > {
473
- fn second < A , B > ( ( _, b) : ( A , B ) ) -> B {
474
- b
475
- }
476
- let second: fn ( ( & ' a String , & ' a Bson ) ) -> & ' a Bson = second;
477
-
466
+ pub fn values ( & self ) -> Values {
478
467
Values {
479
- inner : self . iter ( ) . map ( second ) ,
468
+ inner : self . inner . values ( ) ,
480
469
}
481
470
}
482
471
@@ -498,13 +487,15 @@ impl Document {
498
487
}
499
488
500
489
/// Takes the value of the entry out of the document, and returns it.
490
+ /// Computes in **O(n)** time (average).
501
491
pub fn remove ( & mut self , key : & str ) -> Option < Bson > {
502
- self . inner . remove ( key)
492
+ self . inner . shift_remove ( key)
503
493
}
504
494
505
495
pub fn entry ( & mut self , k : String ) -> Entry {
506
- Entry {
507
- inner : self . inner . entry ( k) ,
496
+ match self . inner . entry ( k) {
497
+ indexmap:: map:: Entry :: Occupied ( o) => Entry :: Occupied ( OccupiedEntry { inner : o } ) ,
498
+ indexmap:: map:: Entry :: Vacant ( v) => Entry :: Vacant ( VacantEntry { inner : v } ) ,
508
499
}
509
500
}
510
501
@@ -575,37 +566,79 @@ impl Document {
575
566
}
576
567
}
577
568
578
- pub struct Entry < ' a > {
579
- inner : linked_hash_map:: Entry < ' a , String , Bson > ,
569
+ /// A view into a single entry in a map, which may either be vacant or occupied.
570
+ ///
571
+ /// This enum is constructed from the entry method on HashMap.
572
+ pub enum Entry < ' a > {
573
+ /// An occupied entry.
574
+ Occupied ( OccupiedEntry < ' a > ) ,
575
+
576
+ /// A vacant entry.
577
+ Vacant ( VacantEntry < ' a > ) ,
580
578
}
581
579
582
580
impl < ' a > Entry < ' a > {
581
+ /// Returns a reference to this entry's key.
583
582
pub fn key ( & self ) -> & str {
584
- self . inner . key ( )
583
+ match self {
584
+ Self :: Vacant ( v) => v. key ( ) ,
585
+ Self :: Occupied ( o) => o. key ( ) ,
586
+ }
585
587
}
586
588
589
+ fn into_indexmap_entry ( self ) -> indexmap:: map:: Entry < ' a , String , Bson > {
590
+ match self {
591
+ Self :: Occupied ( o) => indexmap:: map:: Entry :: Occupied ( o. inner ) ,
592
+ Self :: Vacant ( v) => indexmap:: map:: Entry :: Vacant ( v. inner ) ,
593
+ }
594
+ }
595
+
596
+ /// Inserts the given default value in the entry if it is vacant and returns a mutable reference
597
+ /// to it. Otherwise a mutable reference to an already existent value is returned.
587
598
pub fn or_insert ( self , default : Bson ) -> & ' a mut Bson {
588
- self . inner . or_insert ( default)
599
+ self . into_indexmap_entry ( ) . or_insert ( default)
589
600
}
590
601
602
+ /// Inserts the result of the `default` function in the entry if it is vacant and returns a
603
+ /// mutable reference to it. Otherwise a mutable reference to an already existent value is
604
+ /// returned.
591
605
pub fn or_insert_with < F : FnOnce ( ) -> Bson > ( self , default : F ) -> & ' a mut Bson {
592
- self . inner . or_insert_with ( default)
606
+ self . into_indexmap_entry ( ) . or_insert_with ( default)
607
+ }
608
+ }
609
+
610
+ /// A view into a vacant entry in a [Document]. It is part of the [Entry] enum.
611
+ pub struct VacantEntry < ' a > {
612
+ inner : indexmap:: map:: VacantEntry < ' a , String , Bson > ,
613
+ }
614
+
615
+ impl < ' a > VacantEntry < ' a > {
616
+ /// Gets a reference to the key that would be used when inserting a value through the
617
+ /// [VacantEntry].
618
+ fn key ( & self ) -> & str {
619
+ self . inner . key ( )
593
620
}
594
621
}
595
622
596
- impl From < LinkedHashMap < String , Bson > > for Document {
597
- fn from ( tree : LinkedHashMap < String , Bson > ) -> Document {
598
- Document { inner : tree }
623
+ /// A view into an occupied entry in a [Document]. It is part of the [Entry] enum.
624
+ pub struct OccupiedEntry < ' a > {
625
+ inner : indexmap:: map:: OccupiedEntry < ' a , String , Bson > ,
626
+ }
627
+
628
+ impl < ' a > OccupiedEntry < ' a > {
629
+ /// Gets a reference to the key in the entry.
630
+ pub fn key ( & self ) -> & str {
631
+ self . inner . key ( )
599
632
}
600
633
}
601
634
602
- pub struct DocumentVisitor {
635
+ pub ( crate ) struct DocumentVisitor {
603
636
marker : PhantomData < Document > ,
604
637
}
605
638
606
639
impl DocumentVisitor {
607
640
#[ allow( clippy:: new_without_default) ]
608
- pub fn new ( ) -> DocumentVisitor {
641
+ pub ( crate ) fn new ( ) -> DocumentVisitor {
609
642
DocumentVisitor {
610
643
marker : PhantomData ,
611
644
}
@@ -633,15 +666,15 @@ impl<'de> Visitor<'de> for DocumentVisitor {
633
666
V : MapAccess < ' de > ,
634
667
{
635
668
let mut inner = match visitor. size_hint ( ) {
636
- Some ( size) => LinkedHashMap :: with_capacity ( size) ,
637
- None => LinkedHashMap :: new ( ) ,
669
+ Some ( size) => IndexMap :: with_capacity_and_hasher ( size, RandomState :: default ( ) ) ,
670
+ None => IndexMap :: default ( ) ,
638
671
} ;
639
672
640
673
while let Some ( ( key, value) ) = visitor. next_entry ( ) ? {
641
674
inner. insert ( key, value) ;
642
675
}
643
676
644
- Ok ( inner. into ( ) )
677
+ Ok ( Document { inner } )
645
678
}
646
679
}
647
680
0 commit comments