@@ -74,16 +74,21 @@ pub type Map<K, V> = alloc::collections::BTreeMap<K, V>;
7474/// Generated code delegates to these methods rather than calling inherent
7575/// methods on a concrete type, so users can swap in their own map
7676/// implementation via the `map_type` bindgen option.
77- ///
78- /// The concrete map type must also implement `IntoIterator` (both owned
79- /// and by-ref) yielding key/value pairs.
80- pub trait WitMap < K , V > {
77+ pub trait WitMap < K , V > : Sized {
78+ type Iter : Iterator ;
79+
8180 fn wit_map_new ( capacity : usize ) -> Self ;
8281 fn wit_map_push ( & mut self , key : K , value : V ) ;
8382 fn wit_map_len ( & self ) -> usize ;
83+ fn wit_map_into_iter ( self ) -> Self :: Iter ;
8484}
8585
86- impl < ' a , K , V , T : WitMap < K , V > > WitMap < K , V > for & ' a T {
86+ impl < ' a , K , V , T : WitMap < K , V > > WitMap < K , V > for & ' a T
87+ where
88+ & ' a T : IntoIterator ,
89+ {
90+ type Iter = <& ' a T as IntoIterator >:: IntoIter ;
91+
8792 fn wit_map_new ( _capacity : usize ) -> Self {
8893 unreachable ! ( )
8994 }
@@ -93,9 +98,14 @@ impl<'a, K, V, T: WitMap<K, V>> WitMap<K, V> for &'a T {
9398 fn wit_map_len ( & self ) -> usize {
9499 T :: wit_map_len ( self )
95100 }
101+ fn wit_map_into_iter ( self ) -> Self :: Iter {
102+ self . into_iter ( )
103+ }
96104}
97105
98106impl < K : Ord , V > WitMap < K , V > for alloc:: collections:: BTreeMap < K , V > {
107+ type Iter = alloc:: collections:: btree_map:: IntoIter < K , V > ;
108+
99109 fn wit_map_new ( _capacity : usize ) -> Self {
100110 alloc:: collections:: BTreeMap :: new ( )
101111 }
@@ -105,10 +115,15 @@ impl<K: Ord, V> WitMap<K, V> for alloc::collections::BTreeMap<K, V> {
105115 fn wit_map_len ( & self ) -> usize {
106116 self . len ( )
107117 }
118+ fn wit_map_into_iter ( self ) -> Self :: Iter {
119+ self . into_iter ( )
120+ }
108121}
109122
110123#[ cfg( feature = "std" ) ]
111124impl < K : core:: hash:: Hash + Eq , V > WitMap < K , V > for std:: collections:: HashMap < K , V > {
125+ type Iter = std:: collections:: hash_map:: IntoIter < K , V > ;
126+
112127 fn wit_map_new ( capacity : usize ) -> Self {
113128 std:: collections:: HashMap :: with_capacity ( capacity)
114129 }
@@ -118,6 +133,9 @@ impl<K: core::hash::Hash + Eq, V> WitMap<K, V> for std::collections::HashMap<K,
118133 fn wit_map_len ( & self ) -> usize {
119134 self . len ( )
120135 }
136+ fn wit_map_into_iter ( self ) -> Self :: Iter {
137+ self . into_iter ( )
138+ }
121139}
122140
123141/// For more information about this see `./ci/rebuild-libwit-bindgen-cabi.sh`.
@@ -283,3 +301,81 @@ impl Drop for Cleanup {
283301 }
284302 }
285303}
304+
305+ #[ cfg( test) ]
306+ mod tests {
307+ use super :: * ;
308+ use alloc:: collections:: BTreeMap ;
309+ use alloc:: string:: ToString ;
310+
311+ #[ test]
312+ fn btreemap_new_push_len ( ) {
313+ let mut m: BTreeMap < u32 , alloc:: string:: String > = WitMap :: wit_map_new ( 10 ) ;
314+ assert_eq ! ( WitMap :: <u32 , alloc:: string:: String >:: wit_map_len( & m) , 0 ) ;
315+
316+ WitMap :: wit_map_push ( & mut m, 1 , "one" . to_string ( ) ) ;
317+ WitMap :: wit_map_push ( & mut m, 2 , "two" . to_string ( ) ) ;
318+ assert_eq ! ( WitMap :: <u32 , alloc:: string:: String >:: wit_map_len( & m) , 2 ) ;
319+ }
320+
321+ #[ test]
322+ fn btreemap_into_iter ( ) {
323+ let mut m: BTreeMap < u32 , u32 > = WitMap :: wit_map_new ( 0 ) ;
324+ WitMap :: wit_map_push ( & mut m, 10 , 100 ) ;
325+ WitMap :: wit_map_push ( & mut m, 20 , 200 ) ;
326+
327+ let entries: alloc:: vec:: Vec < _ > = WitMap :: wit_map_into_iter ( m) . collect ( ) ;
328+ assert_eq ! ( entries, alloc:: vec![ ( 10 , 100 ) , ( 20 , 200 ) ] ) ;
329+ }
330+
331+ #[ test]
332+ fn btreemap_duplicate_key_overwrites ( ) {
333+ let mut m: BTreeMap < u32 , u32 > = WitMap :: wit_map_new ( 0 ) ;
334+ WitMap :: wit_map_push ( & mut m, 1 , 10 ) ;
335+ WitMap :: wit_map_push ( & mut m, 1 , 20 ) ;
336+ assert_eq ! ( WitMap :: <u32 , u32 >:: wit_map_len( & m) , 1 ) ;
337+ }
338+
339+ #[ test]
340+ fn ref_blanket_impl_len ( ) {
341+ let mut m: BTreeMap < u32 , u32 > = WitMap :: wit_map_new ( 0 ) ;
342+ WitMap :: wit_map_push ( & mut m, 1 , 10 ) ;
343+
344+ let r = & m;
345+ assert_eq ! ( WitMap :: <u32 , u32 >:: wit_map_len( & r) , 1 ) ;
346+ }
347+
348+ #[ test]
349+ fn ref_blanket_impl_into_iter ( ) {
350+ let mut m: BTreeMap < u32 , u32 > = WitMap :: wit_map_new ( 0 ) ;
351+ WitMap :: wit_map_push ( & mut m, 5 , 50 ) ;
352+
353+ let r = & m;
354+ let entries: alloc:: vec:: Vec < _ > = WitMap :: wit_map_into_iter ( r) . collect ( ) ;
355+ assert_eq ! ( entries, alloc:: vec![ ( & 5 , & 50 ) ] ) ;
356+ }
357+
358+ #[ cfg( feature = "std" ) ]
359+ mod hashmap_tests {
360+ use super :: * ;
361+ use std:: collections:: HashMap ;
362+
363+ #[ test]
364+ fn hashmap_new_push_len ( ) {
365+ let mut m: HashMap < u32 , u32 > = WitMap :: wit_map_new ( 5 ) ;
366+ WitMap :: wit_map_push ( & mut m, 1 , 10 ) ;
367+ WitMap :: wit_map_push ( & mut m, 2 , 20 ) ;
368+ assert_eq ! ( WitMap :: <u32 , u32 >:: wit_map_len( & m) , 2 ) ;
369+ }
370+
371+ #[ test]
372+ fn hashmap_into_iter ( ) {
373+ let mut m: HashMap < u32 , u32 > = WitMap :: wit_map_new ( 0 ) ;
374+ WitMap :: wit_map_push ( & mut m, 1 , 10 ) ;
375+
376+ let entries: alloc:: vec:: Vec < _ > = WitMap :: wit_map_into_iter ( m) . collect ( ) ;
377+ assert_eq ! ( entries. len( ) , 1 ) ;
378+ assert_eq ! ( entries[ 0 ] , ( 1 , 10 ) ) ;
379+ }
380+ }
381+ }
0 commit comments