@@ -537,7 +537,7 @@ impl HeaderMap {
537537 /// assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
538538 /// ```
539539 pub fn iter ( & self ) -> Iter < ' _ > {
540- Iter :: new ( self . inner . iter ( ) )
540+ Iter :: new ( self . inner . iter ( ) , self . len ( ) )
541541 }
542542
543543 /// An iterator over all contained header names.
@@ -626,7 +626,8 @@ impl HeaderMap {
626626 /// assert!(map.is_empty());
627627 /// ```
628628 pub fn drain ( & mut self ) -> Drain < ' _ > {
629- Drain :: new ( self . inner . drain ( ) )
629+ let len = self . len ( ) ;
630+ Drain :: new ( self . inner . drain ( ) , len)
630631 }
631632}
632633
@@ -638,7 +639,8 @@ impl IntoIterator for HeaderMap {
638639
639640 #[ inline]
640641 fn into_iter ( self ) -> Self :: IntoIter {
641- IntoIter :: new ( self . inner . into_iter ( ) )
642+ let len = self . len ( ) ;
643+ IntoIter :: new ( self . inner . into_iter ( ) , len)
642644 }
643645}
644646
@@ -648,7 +650,7 @@ impl<'a> IntoIterator for &'a HeaderMap {
648650
649651 #[ inline]
650652 fn into_iter ( self ) -> Self :: IntoIter {
651- Iter :: new ( self . inner . iter ( ) )
653+ Iter :: new ( self . inner . iter ( ) , self . len ( ) )
652654 }
653655}
654656
@@ -760,14 +762,16 @@ pub struct Iter<'a> {
760762 inner : hash_map:: Iter < ' a , HeaderName , Value > ,
761763 multi_inner : Option < ( & ' a HeaderName , & ' a SmallVec < [ HeaderValue ; 4 ] > ) > ,
762764 multi_idx : usize ,
765+ remaining : usize ,
763766}
764767
765768impl < ' a > Iter < ' a > {
766- fn new ( iter : hash_map:: Iter < ' a , HeaderName , Value > ) -> Self {
769+ fn new ( iter : hash_map:: Iter < ' a , HeaderName , Value > , remaining : usize ) -> Self {
767770 Self {
768771 inner : iter,
769772 multi_idx : 0 ,
770773 multi_inner : None ,
774+ remaining,
771775 }
772776 }
773777}
@@ -781,6 +785,7 @@ impl<'a> Iterator for Iter<'a> {
781785 match vals. get ( self . multi_idx ) {
782786 Some ( val) => {
783787 self . multi_idx += 1 ;
788+ self . remaining -= 1 ;
784789 return Some ( ( name, val) ) ;
785790 }
786791 None => {
@@ -800,9 +805,7 @@ impl<'a> Iterator for Iter<'a> {
800805
801806 #[ inline]
802807 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
803- // take inner lower bound
804- // make no attempt at an upper bound
805- ( self . inner . size_hint ( ) . 0 , None )
808+ ( self . remaining , Some ( self . remaining ) )
806809 }
807810}
808811
@@ -818,14 +821,16 @@ pub struct Drain<'a> {
818821 inner : hash_map:: Drain < ' a , HeaderName , Value > ,
819822 multi_inner : Option < ( Option < HeaderName > , SmallVec < [ HeaderValue ; 4 ] > ) > ,
820823 multi_idx : usize ,
824+ remaining : usize ,
821825}
822826
823827impl < ' a > Drain < ' a > {
824- fn new ( iter : hash_map:: Drain < ' a , HeaderName , Value > ) -> Self {
828+ fn new ( iter : hash_map:: Drain < ' a , HeaderName , Value > , remaining : usize ) -> Self {
825829 Self {
826830 inner : iter,
827831 multi_inner : None ,
828832 multi_idx : 0 ,
833+ remaining,
829834 }
830835 }
831836}
@@ -838,6 +843,7 @@ impl Iterator for Drain<'_> {
838843 if let Some ( ( ref mut name, ref mut vals) ) = self . multi_inner {
839844 if !vals. is_empty ( ) {
840845 // OPTIMIZE: array removals
846+ self . remaining -= 1 ;
841847 return Some ( ( name. take ( ) , vals. remove ( 0 ) ) ) ;
842848 } else {
843849 // no more items in value iterator; reset state
@@ -855,9 +861,7 @@ impl Iterator for Drain<'_> {
855861
856862 #[ inline]
857863 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
858- // take inner lower bound
859- // make no attempt at an upper bound
860- ( self . inner . size_hint ( ) . 0 , None )
864+ ( self . remaining , Some ( self . remaining ) )
861865 }
862866}
863867
@@ -872,13 +876,15 @@ impl iter::FusedIterator for Drain<'_> {}
872876pub struct IntoIter {
873877 inner : hash_map:: IntoIter < HeaderName , Value > ,
874878 multi_inner : Option < ( HeaderName , smallvec:: IntoIter < [ HeaderValue ; 4 ] > ) > ,
879+ remaining : usize ,
875880}
876881
877882impl IntoIter {
878- fn new ( inner : hash_map:: IntoIter < HeaderName , Value > ) -> Self {
883+ fn new ( inner : hash_map:: IntoIter < HeaderName , Value > , remaining : usize ) -> Self {
879884 Self {
880885 inner,
881886 multi_inner : None ,
887+ remaining,
882888 }
883889 }
884890}
@@ -891,6 +897,7 @@ impl Iterator for IntoIter {
891897 if let Some ( ( ref name, ref mut vals) ) = self . multi_inner {
892898 match vals. next ( ) {
893899 Some ( val) => {
900+ self . remaining -= 1 ;
894901 return Some ( ( name. clone ( ) , val) ) ;
895902 }
896903 None => {
@@ -909,9 +916,7 @@ impl Iterator for IntoIter {
909916
910917 #[ inline]
911918 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
912- // take inner lower bound
913- // make no attempt at an upper bound
914- ( self . inner . size_hint ( ) . 0 , None )
919+ ( self . remaining , Some ( self . remaining ) )
915920 }
916921}
917922
@@ -1160,6 +1165,40 @@ mod tests {
11601165 assert ! ( vals. next( ) . is_none( ) ) ;
11611166 }
11621167
1168+ #[ test]
1169+ fn iter_len_counts_values ( ) {
1170+ let mut map = HeaderMap :: new ( ) ;
1171+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "a=1" ) ) ;
1172+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "b=2" ) ) ;
1173+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "c=3" ) ) ;
1174+
1175+ assert_eq ! ( map. iter( ) . count( ) , 3 ) ;
1176+ assert_eq ! ( map. iter( ) . len( ) , 3 ) ;
1177+ }
1178+
1179+ #[ test]
1180+ fn into_iter_len_counts_values ( ) {
1181+ let mut map = HeaderMap :: new ( ) ;
1182+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "a=1" ) ) ;
1183+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "b=2" ) ) ;
1184+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "c=3" ) ) ;
1185+
1186+ assert_eq ! ( map. clone( ) . into_iter( ) . count( ) , 3 ) ;
1187+ assert_eq ! ( map. into_iter( ) . len( ) , 3 ) ;
1188+ }
1189+
1190+ #[ test]
1191+ fn drain_len_counts_values ( ) {
1192+ let mut map = HeaderMap :: new ( ) ;
1193+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "a=1" ) ) ;
1194+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "b=2" ) ) ;
1195+ map. append ( header:: SET_COOKIE , HeaderValue :: from_static ( "c=3" ) ) ;
1196+
1197+ let mut drained = map. clone ( ) ;
1198+ assert_eq ! ( map. drain( ) . count( ) , 3 ) ;
1199+ assert_eq ! ( drained. drain( ) . len( ) , 3 ) ;
1200+ }
1201+
11631202 fn owned_pair < ' a > ( ( name, val) : ( & ' a HeaderName , & ' a HeaderValue ) ) -> ( HeaderName , HeaderValue ) {
11641203 ( name. clone ( ) , val. clone ( ) )
11651204 }
0 commit comments