1
- use std:: { borrow:: Cow , fmt, marker :: PhantomData } ;
1
+ use std:: { borrow:: Cow , fmt, slice } ;
2
2
3
3
use value_bag:: { OwnedValueBag , ValueBag } ;
4
4
@@ -73,40 +73,50 @@ impl KeyOwned {
73
73
pub type Value < ' a > = ValueBag < ' a > ;
74
74
pub ( crate ) type ValueOwned = OwnedValueBag ;
75
75
76
- pub struct KeyValuesIter < ' a , I > {
77
- iter : I ,
78
- len : usize ,
79
- phantom : PhantomData < & ' a ( ) > ,
76
+ enum KeyValuesInner < ' a > {
77
+ Borrowed ( & ' a [ Pair < ' a > ] ) ,
78
+ Owned ( & ' a [ ( KeyOwned , ValueOwned ) ] ) ,
80
79
}
80
+ enum KeyValuesIterInner < ' a > {
81
+ Borrowed ( slice:: Iter < ' a , Pair < ' a > > ) ,
82
+ Owned ( slice:: Iter < ' a , ( KeyOwned , ValueOwned ) > ) ,
83
+ }
84
+
85
+ pub struct KeyValues < ' a > ( KeyValuesInner < ' a > ) ;
81
86
82
- impl < I > KeyValuesIter < ' _ , I > {
87
+ impl < ' a > KeyValues < ' a > {
83
88
pub fn len ( & self ) -> usize {
84
- self . len
89
+ match self . 0 {
90
+ KeyValuesInner :: Borrowed ( p) => p. len ( ) ,
91
+ KeyValuesInner :: Owned ( p) => p. len ( ) ,
92
+ }
85
93
}
86
94
87
95
pub fn is_empty ( & self ) -> bool {
88
- self . len == 0
96
+ match self . 0 {
97
+ KeyValuesInner :: Borrowed ( p) => p. is_empty ( ) ,
98
+ KeyValuesInner :: Owned ( p) => p. is_empty ( ) ,
99
+ }
89
100
}
90
- }
91
101
92
- impl < ' a , I > KeyValuesIter < ' a , I >
93
- where
94
- I : Iterator < Item = ( Key < ' a > , Value < ' a > ) > ,
95
- {
96
- pub ( crate ) fn new ( iter : I , len : usize ) -> Self {
97
- Self {
98
- iter,
99
- len,
100
- phantom : PhantomData ,
102
+ pub fn iter ( & self ) -> KeyValuesIter < ' a > {
103
+ match & self . 0 {
104
+ KeyValuesInner :: Borrowed ( p) => KeyValuesIter ( KeyValuesIterInner :: Borrowed ( p. iter ( ) ) ) ,
105
+ KeyValuesInner :: Owned ( p) => KeyValuesIter ( KeyValuesIterInner :: Owned ( p. iter ( ) ) ) ,
101
106
}
102
107
}
103
108
104
- pub ( crate ) fn write_to (
105
- mut self ,
106
- dest : & mut impl fmt:: Write ,
107
- leading_space : bool ,
108
- ) -> fmt:: Result {
109
- let first = self . next ( ) ;
109
+ pub ( crate ) fn with_borrowed ( pairs : & ' a [ Pair < ' a > ] ) -> Self {
110
+ Self ( KeyValuesInner :: Borrowed ( pairs) )
111
+ }
112
+
113
+ pub ( crate ) fn with_owned ( pairs : & ' a [ ( KeyOwned , ValueOwned ) ] ) -> Self {
114
+ Self ( KeyValuesInner :: Owned ( pairs) )
115
+ }
116
+
117
+ pub ( crate ) fn write_to ( & self , dest : & mut impl fmt:: Write , leading_space : bool ) -> fmt:: Result {
118
+ let mut iter = self . iter ( ) ;
119
+ let first = iter. next ( ) ;
110
120
if let Some ( ( key, value) ) = first {
111
121
if leading_space {
112
122
dest. write_str ( " { " ) ?;
@@ -120,7 +130,7 @@ where
120
130
dest. write_str ( "=" ) ?;
121
131
write ! ( dest, "{}" , value) ?;
122
132
123
- for ( key, value) in self {
133
+ for ( key, value) in iter {
124
134
dest. write_str ( ", " ) ?;
125
135
dest. write_str ( key. as_str ( ) ) ?;
126
136
dest. write_str ( "=" ) ?;
@@ -133,18 +143,33 @@ where
133
143
}
134
144
}
135
145
136
- impl < ' a , I > Iterator for KeyValuesIter < ' a , I >
137
- where
138
- I : Iterator < Item = ( Key < ' a > , Value < ' a > ) > ,
139
- {
140
- type Item = I :: Item ;
146
+ impl < ' a > IntoIterator for KeyValues < ' a > {
147
+ type Item = Pair < ' a > ;
148
+ type IntoIter = KeyValuesIter < ' a > ;
149
+
150
+ fn into_iter ( self ) -> Self :: IntoIter {
151
+ self . iter ( )
152
+ }
153
+ }
154
+
155
+ pub struct KeyValuesIter < ' a > ( KeyValuesIterInner < ' a > ) ;
156
+
157
+ impl < ' a > Iterator for KeyValuesIter < ' a > {
158
+ type Item = Pair < ' a > ;
141
159
142
160
fn next ( & mut self ) -> Option < Self :: Item > {
143
- self . iter . next ( )
161
+ match & mut self . 0 {
162
+ // The 2 clones should be cheap
163
+ KeyValuesIterInner :: Borrowed ( iter) => iter. next ( ) . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) ) ,
164
+ KeyValuesIterInner :: Owned ( iter) => iter. next ( ) . map ( |( k, v) | ( k. as_ref ( ) , v. by_ref ( ) ) ) ,
165
+ }
144
166
}
145
167
146
168
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
147
- self . iter . size_hint ( )
169
+ match & self . 0 {
170
+ KeyValuesIterInner :: Borrowed ( iter) => iter. size_hint ( ) ,
171
+ KeyValuesIterInner :: Owned ( iter) => iter. size_hint ( ) ,
172
+ }
148
173
}
149
174
}
150
175
0 commit comments