@@ -126,21 +126,6 @@ macro_rules! string_impl {
126
126
) -> bool ;
127
127
}
128
128
129
- impl Default for $string {
130
- fn default ( ) -> Self {
131
- let mut msg = Self {
132
- data: std:: ptr:: null_mut( ) ,
133
- size: 0 ,
134
- capacity: 0 ,
135
- } ;
136
- // SAFETY: Passing in a zeroed string is safe.
137
- if !unsafe { $init( & mut msg as * mut _) } {
138
- panic!( "Sinit failed" ) ;
139
- }
140
- msg
141
- }
142
- }
143
-
144
129
impl Clone for $string {
145
130
fn clone( & self ) -> Self {
146
131
let mut msg = Self :: default ( ) ;
@@ -158,6 +143,21 @@ macro_rules! string_impl {
158
143
}
159
144
}
160
145
146
+ impl Default for $string {
147
+ fn default ( ) -> Self {
148
+ let mut msg = Self {
149
+ data: std:: ptr:: null_mut( ) ,
150
+ size: 0 ,
151
+ capacity: 0 ,
152
+ } ;
153
+ // SAFETY: Passing in a zeroed string is safe.
154
+ if !unsafe { $init( & mut msg as * mut _) } {
155
+ panic!( "$init failed" ) ;
156
+ }
157
+ msg
158
+ }
159
+ }
160
+
161
161
// It's not guaranteed that there are no interior null bytes, hence no Deref to CStr.
162
162
// This does not include the null byte at the end!
163
163
impl Deref for $string {
@@ -200,15 +200,39 @@ macro_rules! string_impl {
200
200
201
201
impl Eq for $string { }
202
202
203
- impl Hash for $string {
204
- fn hash<H : Hasher >( & self , state: & mut H ) {
205
- self . deref( ) . hash( state)
203
+ impl Extend <char > for $string {
204
+ fn extend<I : IntoIterator <Item = char >>( & mut self , iter: I ) {
205
+ let mut s = self . to_string( ) ;
206
+ s. extend( iter) ;
207
+ * self = Self :: from( s. as_str( ) ) ;
206
208
}
207
209
}
208
210
209
- impl PartialEq for $string {
210
- fn eq( & self , other: & Self ) -> bool {
211
- self . deref( ) . eq( other. deref( ) )
211
+ impl <' a> Extend <& ' a char > for $string {
212
+ fn extend<I : IntoIterator <Item = & ' a char >>( & mut self , iter: I ) {
213
+ self . extend( iter. into_iter( ) . cloned( ) ) ;
214
+ }
215
+ }
216
+
217
+ impl FromIterator <char > for $string {
218
+ fn from_iter<I : IntoIterator <Item = char >>( iter: I ) -> Self {
219
+ let mut buf = <$string>:: default ( ) ;
220
+ buf. extend( iter) ;
221
+ buf
222
+ }
223
+ }
224
+
225
+ impl <' a> FromIterator <& ' a char > for $string {
226
+ fn from_iter<I : IntoIterator <Item = & ' a char >>( iter: I ) -> Self {
227
+ let mut buf = <$string>:: default ( ) ;
228
+ buf. extend( iter) ;
229
+ buf
230
+ }
231
+ }
232
+
233
+ impl Hash for $string {
234
+ fn hash<H : Hasher >( & self , state: & mut H ) {
235
+ self . deref( ) . hash( state)
212
236
}
213
237
}
214
238
@@ -218,6 +242,12 @@ macro_rules! string_impl {
218
242
}
219
243
}
220
244
245
+ impl PartialEq for $string {
246
+ fn eq( & self , other: & Self ) -> bool {
247
+ self . deref( ) . eq( other. deref( ) )
248
+ }
249
+ }
250
+
221
251
impl PartialOrd for $string {
222
252
fn partial_cmp( & self , other: & Self ) -> Option <Ordering > {
223
253
self . deref( ) . partial_cmp( other. deref( ) )
@@ -503,4 +533,64 @@ mod tests {
503
533
s. as_str ( ) . try_into ( ) . unwrap ( )
504
534
}
505
535
}
536
+
537
+ #[ test]
538
+ fn string_from_char_iterator ( ) {
539
+ // Base char case
540
+ let expected = String :: from ( "abc" ) ;
541
+ let actual = "abc" . chars ( ) . collect :: < String > ( ) ;
542
+
543
+ assert_eq ! ( expected, actual) ;
544
+
545
+ // Empty case
546
+ let expected = String :: from ( "" ) ;
547
+ let actual = "" . chars ( ) . collect :: < String > ( ) ;
548
+
549
+ assert_eq ! ( expected, actual) ;
550
+
551
+ // Non-ascii char case
552
+ let expected = String :: from ( "Grüß Gott! 𝕊" ) ;
553
+ let actual = "Grüß Gott! 𝕊" . chars ( ) . collect :: < String > ( ) ;
554
+
555
+ assert_eq ! ( expected, actual) ;
556
+ }
557
+
558
+ #[ test]
559
+ fn extend_string_with_char_iterator ( ) {
560
+ let expected = WString :: from ( "abcdef" ) ;
561
+ let mut actual = WString :: from ( "abc" ) ;
562
+ actual. extend ( "def" . chars ( ) ) ;
563
+
564
+ assert_eq ! ( expected, actual) ;
565
+ }
566
+
567
+ #[ test]
568
+ fn wstring_from_char_iterator ( ) {
569
+ // Base char case
570
+ let expected = WString :: from ( "abc" ) ;
571
+ let actual = "abc" . chars ( ) . collect :: < WString > ( ) ;
572
+
573
+ assert_eq ! ( expected, actual) ;
574
+
575
+ // Empty case
576
+ let expected = WString :: from ( "" ) ;
577
+ let actual = "" . chars ( ) . collect :: < WString > ( ) ;
578
+
579
+ assert_eq ! ( expected, actual) ;
580
+
581
+ // Non-ascii char case
582
+ let expected = WString :: from ( "Grüß Gott! 𝕊" ) ;
583
+ let actual = "Grüß Gott! 𝕊" . chars ( ) . collect :: < WString > ( ) ;
584
+
585
+ assert_eq ! ( expected, actual) ;
586
+ }
587
+
588
+ #[ test]
589
+ fn extend_wstring_with_char_iterator ( ) {
590
+ let expected = WString :: from ( "abcdef" ) ;
591
+ let mut actual = WString :: from ( "abc" ) ;
592
+ actual. extend ( "def" . chars ( ) ) ;
593
+
594
+ assert_eq ! ( expected, actual) ;
595
+ }
506
596
}
0 commit comments