@@ -9,7 +9,7 @@ use std::borrow::{Borrow, Cow};
9
9
use std:: marker:: PhantomData ;
10
10
use std:: cell:: Cell ;
11
11
use std:: ops:: { Deref , DerefMut } ;
12
- use std:: iter:: IntoIterator ;
12
+ use std:: iter:: FromIterator ;
13
13
use std:: io:: Write ;
14
14
use std:: default:: Default ;
15
15
use std:: cmp:: Ordering ;
@@ -147,8 +147,118 @@ impl<F> Drop for Tendril<F>
147
147
}
148
148
}
149
149
150
- // impl FromIterator<char> for Tendril<fmt::UTF8> { }
151
- // impl FromIterator<u8> for Tendril<fmt::Bytes> { }
150
+ macro_rules! from_iter_method {
151
+ ( $ty: ty) => {
152
+ #[ inline]
153
+ fn from_iter<I >( iterable: I ) -> Self
154
+ where I : IntoIterator <Item = $ty>
155
+ {
156
+ let mut output = Self :: new( ) ;
157
+ output. extend( iterable) ;
158
+ output
159
+ }
160
+ }
161
+ }
162
+
163
+ impl Extend < char > for Tendril < fmt:: UTF8 > {
164
+ #[ inline]
165
+ fn extend < I > ( & mut self , iterable : I )
166
+ where I : IntoIterator < Item = char > ,
167
+ {
168
+ let iterator = iterable. into_iter ( ) ;
169
+ self . force_reserve ( iterator. size_hint ( ) . 0 as u32 ) ;
170
+ for c in iterator {
171
+ self . push_char ( c) ;
172
+ }
173
+ }
174
+ }
175
+
176
+ impl FromIterator < char > for Tendril < fmt:: UTF8 > {
177
+ from_iter_method ! ( char ) ;
178
+ }
179
+
180
+ impl Extend < u8 > for Tendril < fmt:: Bytes > {
181
+ #[ inline]
182
+ fn extend < I > ( & mut self , iterable : I )
183
+ where I : IntoIterator < Item = u8 > ,
184
+ {
185
+ let iterator = iterable. into_iter ( ) ;
186
+ self . force_reserve ( iterator. size_hint ( ) . 0 as u32 ) ;
187
+ for b in iterator {
188
+ self . push_slice ( & [ b] ) ;
189
+ }
190
+ }
191
+ }
192
+
193
+ impl FromIterator < u8 > for Tendril < fmt:: Bytes > {
194
+ from_iter_method ! ( u8 ) ;
195
+ }
196
+
197
+ impl < ' a > Extend < & ' a u8 > for Tendril < fmt:: Bytes > {
198
+ #[ inline]
199
+ fn extend < I > ( & mut self , iterable : I )
200
+ where I : IntoIterator < Item = & ' a u8 > ,
201
+ {
202
+ let iterator = iterable. into_iter ( ) ;
203
+ self . force_reserve ( iterator. size_hint ( ) . 0 as u32 ) ;
204
+ for & b in iterator {
205
+ self . push_slice ( & [ b] ) ;
206
+ }
207
+ }
208
+ }
209
+
210
+ impl < ' a > FromIterator < & ' a u8 > for Tendril < fmt:: Bytes > {
211
+ from_iter_method ! ( & ' a u8 ) ;
212
+ }
213
+
214
+ impl < ' a > Extend < & ' a str > for Tendril < fmt:: UTF8 > {
215
+ #[ inline]
216
+ fn extend < I > ( & mut self , iterable : I )
217
+ where I : IntoIterator < Item = & ' a str > ,
218
+ {
219
+ for s in iterable {
220
+ self . push_slice ( s) ;
221
+ }
222
+ }
223
+ }
224
+
225
+ impl < ' a > FromIterator < & ' a str > for Tendril < fmt:: UTF8 > {
226
+ from_iter_method ! ( & ' a str ) ;
227
+ }
228
+
229
+ impl < ' a > Extend < & ' a [ u8 ] > for Tendril < fmt:: Bytes > {
230
+ #[ inline]
231
+ fn extend < I > ( & mut self , iterable : I )
232
+ where I : IntoIterator < Item = & ' a [ u8 ] > ,
233
+ {
234
+ for s in iterable {
235
+ self . push_slice ( s) ;
236
+ }
237
+ }
238
+ }
239
+
240
+ impl < ' a > FromIterator < & ' a [ u8 ] > for Tendril < fmt:: Bytes > {
241
+ from_iter_method ! ( & ' a [ u8 ] ) ;
242
+ }
243
+
244
+ impl < ' a , F > Extend < & ' a Tendril < F > > for Tendril < F >
245
+ where F : fmt:: Format + ' a ,
246
+ {
247
+ #[ inline]
248
+ fn extend < I > ( & mut self , iterable : I )
249
+ where I : IntoIterator < Item = & ' a Tendril < F > > ,
250
+ {
251
+ for t in iterable {
252
+ self . push_tendril ( t) ;
253
+ }
254
+ }
255
+ }
256
+
257
+ impl < ' a , F > FromIterator < & ' a Tendril < F > > for Tendril < F >
258
+ where F : fmt:: Format + ' a ,
259
+ {
260
+ from_iter_method ! ( & ' a Tendril <F >) ;
261
+ }
152
262
153
263
impl < F > Deref for Tendril < F >
154
264
where F : fmt:: SliceFormat ,
@@ -175,20 +285,6 @@ impl<F> Borrow<[u8]> for Tendril<F>
175
285
// and so a HashMap<StrTendril, _> would silently break if we indexed by str. Ick.
176
286
// https://github.com/rust-lang/rust/issues/27108
177
287
178
- impl < ' a , F > Extend < & ' a Tendril < F > > for Tendril < F >
179
- where F : fmt:: Format + ' a ,
180
- {
181
- #[ inline]
182
- fn extend < I > ( & mut self , iterable : I )
183
- where I : IntoIterator < Item = & ' a Tendril < F > > ,
184
- {
185
- let iterator = iterable. into_iter ( ) ;
186
- for t in iterator {
187
- self . push_tendril ( t) ;
188
- }
189
- }
190
- }
191
-
192
288
impl < F > PartialEq for Tendril < F >
193
289
where F : fmt:: Format ,
194
290
{
@@ -292,12 +388,16 @@ impl<F> Tendril<F>
292
388
/// decline to allocate until the buffer is actually modified.
293
389
#[ inline]
294
390
pub fn reserve ( & mut self , additional : u32 ) {
295
- if self . is_shared ( ) {
391
+ if ! self . is_shared ( ) {
296
392
// Don't grow a shared tendril because we'd have to copy
297
393
// right away.
298
- return ;
394
+ self . force_reserve ( additional ) ;
299
395
}
396
+ }
300
397
398
+ /// Reserve space for additional bytes, even for shared buffers.
399
+ #[ inline]
400
+ fn force_reserve ( & mut self , additional : u32 ) {
301
401
let new_len = self . len32 ( ) . checked_add ( additional) . expect ( OFLOW ) ;
302
402
if new_len > MAX_INLINE_LEN as u32 {
303
403
unsafe {
@@ -1698,12 +1798,60 @@ mod test {
1698
1798
}
1699
1799
1700
1800
#[ test]
1701
- fn extend ( ) {
1801
+ fn extend_and_from_iterator ( ) {
1802
+ // Testing Extend<T> and FromIterator<T> for the various Ts.
1803
+
1804
+ // Tendril<F>
1702
1805
let mut t = "Hello" . to_tendril ( ) ;
1703
- t. extend ( None . into_iter ( ) ) ;
1806
+ t. extend ( None :: < & Tendril < _ > > . into_iter ( ) ) ;
1704
1807
assert_eq ! ( "Hello" , & * t) ;
1705
1808
t. extend ( & [ ", " . to_tendril ( ) , "world" . to_tendril ( ) , "!" . to_tendril ( ) ] ) ;
1706
1809
assert_eq ! ( "Hello, world!" , & * t) ;
1810
+ assert_eq ! ( "Hello, world!" , & * [ "Hello" . to_tendril( ) , ", " . to_tendril( ) ,
1811
+ "world" . to_tendril( ) , "!" . to_tendril( ) ]
1812
+ . iter( ) . collect:: <StrTendril >( ) ) ;
1813
+
1814
+ // &str
1815
+ let mut t = "Hello" . to_tendril ( ) ;
1816
+ t. extend ( None :: < & str > . into_iter ( ) ) ;
1817
+ assert_eq ! ( "Hello" , & * t) ;
1818
+ t. extend ( [ ", " , "world" , "!" ] . iter ( ) . map ( |& s| s) ) ;
1819
+ assert_eq ! ( "Hello, world!" , & * t) ;
1820
+ assert_eq ! ( "Hello, world!" , & * [ "Hello" , ", " , "world" , "!" ]
1821
+ . iter( ) . map( |& s| s) . collect:: <StrTendril >( ) ) ;
1822
+
1823
+ // &[u8]
1824
+ let mut t = b"Hello" . to_tendril ( ) ;
1825
+ t. extend ( None :: < & [ u8 ] > . into_iter ( ) ) ;
1826
+ assert_eq ! ( b"Hello" , & * t) ;
1827
+ t. extend ( [ b", " as & [ u8 ] , b"world" as & [ u8 ] , b"!" as & [ u8 ] ] . iter ( ) . map ( |& s| s) ) ;
1828
+ assert_eq ! ( b"Hello, world!" , & * t) ;
1829
+ assert_eq ! ( b"Hello, world!" , & * [ b"Hello" as & [ u8 ] , b", " as & [ u8 ] ,
1830
+ b"world" as & [ u8 ] , b"!" as & [ u8 ] ]
1831
+ . iter( ) . map( |& s| s) . collect:: <ByteTendril >( ) ) ;
1832
+
1833
+ let string = "the quick brown fox jumps over the lazy dog" ;
1834
+ let string_expected = string. to_tendril ( ) ;
1835
+ let bytes = string. as_bytes ( ) ;
1836
+ let bytes_expected = bytes. to_tendril ( ) ;
1837
+
1838
+ // char
1839
+ assert_eq ! ( string_expected, string. chars( ) . collect( ) ) ;
1840
+ let mut tendril = StrTendril :: new ( ) ;
1841
+ tendril. extend ( string. chars ( ) ) ;
1842
+ assert_eq ! ( string_expected, tendril) ;
1843
+
1844
+ // &u8
1845
+ assert_eq ! ( bytes_expected, bytes. iter( ) . collect( ) ) ;
1846
+ let mut tendril = ByteTendril :: new ( ) ;
1847
+ tendril. extend ( bytes) ;
1848
+ assert_eq ! ( bytes_expected, tendril) ;
1849
+
1850
+ // u8
1851
+ assert_eq ! ( bytes_expected, bytes. iter( ) . map( |& b| b) . collect( ) ) ;
1852
+ let mut tendril = ByteTendril :: new ( ) ;
1853
+ tendril. extend ( bytes. iter ( ) . map ( |& b| b) ) ;
1854
+ assert_eq ! ( bytes_expected, tendril) ;
1707
1855
}
1708
1856
1709
1857
#[ test]
0 commit comments