@@ -369,19 +369,19 @@ impl<K: Ord + Clone, V> MarkMap<K, V> {
369369 /// For the behavior of exclusive or mark the behavior as also `Mark::Required`, then after merge call `missing()`
370370 /// to check all required values.
371371 #[ doc( hidden) ]
372- pub fn merge_from ( & mut self , other : Self ) -> Result < ( ) , MergeError < K , Box < V > > > {
373- for ( their_key, their_mark, their_val) in other. contents {
372+ pub fn merge_from ( & mut self , mut other : Self ) -> Result < ( ) , MergeError < K , Box < V > > > {
373+ for ( their_key, their_mark, their_val) in other. contents . drain ( .. ) {
374374 let pos = self . contents . binary_search_by ( |x| x. 0 . cmp ( & their_key) ) ;
375375 match pos {
376376 Ok ( pos) => {
377- let ( _, my_mark, my_val) = & self . contents [ pos] ;
377+ let ( _, my_mark, my_val) = & mut self . contents [ pos] ;
378378 let theirs_mark = Mark :: MergeBehavior ( MergeBehavior :: Theirs ) . repr ( ) ;
379379 let ours_mark = Mark :: MergeBehavior ( MergeBehavior :: Ours ) . repr ( ) ;
380380 let exclusive_mark =
381381 Mark :: MergeBehavior ( MergeBehavior :: MutuallyExclusive ) . repr ( ) ;
382- let merge_behavior = ( my_mark & exclusive_mark)
383- | ( my_mark & ours_mark)
384- | ( my_mark & theirs_mark) ;
382+ let merge_behavior = ( * my_mark & exclusive_mark)
383+ | ( * my_mark & ours_mark)
384+ | ( * my_mark & theirs_mark) ;
385385 if merge_behavior == exclusive_mark || merge_behavior == 0 {
386386 // If only clippy could convince me and the borrow checker this is actually unnecessary.
387387 #[ allow( clippy:: unnecessary_unwrap) ]
@@ -391,18 +391,13 @@ impl<K: Ord + Clone, V> MarkMap<K, V> {
391391 Box :: new ( their_val. unwrap ( ) ) ,
392392 ) ) ;
393393 } else if my_val. is_none ( ) {
394- self . contents [ pos] . 2 = their_val;
395- return Ok ( ( ) ) ;
394+ * my_val = their_val;
396395 }
397- }
398- if merge_behavior == theirs_mark && their_val. is_some ( ) {
399- self . contents [ pos] . 2 = their_val;
400- return Ok ( ( ) ) ;
401- }
402-
403- if merge_behavior == ours_mark && my_val. is_none ( ) {
404- self . contents [ pos] . 2 = their_val;
405- return Ok ( ( ) ) ;
396+ } else if merge_behavior == theirs_mark && their_val. is_some ( )
397+ || merge_behavior == ours_mark && my_val. is_none ( )
398+ {
399+ * my_mark = their_mark;
400+ * my_val = their_val;
406401 }
407402 }
408403 Err ( pos) => {
@@ -457,6 +452,12 @@ impl<K: Ord + Clone, V> MarkMap<K, V> {
457452 }
458453 ret
459454 }
455+
456+ /// Returns an `Iterator` over all the keys of the `MarkMap`.
457+ #[ doc( hidden) ]
458+ pub fn keys ( & self ) -> Keys < ' _ , K , V > {
459+ Keys { pos : 0 , map : self }
460+ }
460461}
461462
462463/// Iterator over the owned keys and values of a `MarkMap`.
@@ -509,6 +510,30 @@ impl<'a, K, V> IntoIterator for &'a MarkMap<K, V> {
509510 }
510511}
511512
513+ /// Iterator over references to keys and values of a `MarkMap`.
514+ #[ doc( hidden) ]
515+ pub struct Keys < ' a , K , V > {
516+ pos : usize ,
517+ map : & ' a MarkMap < K , V > ,
518+ }
519+
520+ impl < ' a , K , V > Iterator for Keys < ' a , K , V > {
521+ type Item = & ' a K ;
522+
523+ fn next ( & mut self ) -> Option < Self :: Item > {
524+ loop {
525+ if self . pos >= self . map . contents . len ( ) {
526+ return None ;
527+ }
528+ let pos = self . pos ;
529+ self . pos += 1 ;
530+ if self . map . contents [ pos] . 2 . is_some ( ) {
531+ return Some ( & self . map . contents [ pos] . 0 ) ;
532+ }
533+ }
534+ }
535+ }
536+
512537#[ cfg( test) ]
513538mod test {
514539 use super :: * ;
@@ -828,4 +853,21 @@ mod test {
828853 assert ! ( mm. is_required( & "a" ) ) ;
829854 assert ! ( mm. is_used( & "a" ) ) ;
830855 }
856+
857+ #[ test]
858+ fn test_merge_many ( ) {
859+ let mut mm = MarkMap :: new ( ) ;
860+ mm. insert ( "a" , ( ) ) ;
861+ mm. insert ( "b" , ( ) ) ;
862+
863+ let mut mm2 = MarkMap :: new ( ) ;
864+ mm2. insert ( "x" , ( ) ) ;
865+ mm2. insert ( "y" , ( ) ) ;
866+
867+ mm. merge_from ( mm2) . unwrap ( ) ;
868+ assert_eq ! (
869+ mm. keys( ) . cloned( ) . collect:: <Vec <_>>( ) ,
870+ vec![ "a" , "b" , "x" , "y" ]
871+ ) ;
872+ }
831873}
0 commit comments