@@ -126,21 +126,6 @@ macro_rules! string_impl {
126126 ) -> bool ;
127127 }
128128
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-
144129 impl Clone for $string {
145130 fn clone( & self ) -> Self {
146131 let mut msg = Self :: default ( ) ;
@@ -158,6 +143,21 @@ macro_rules! string_impl {
158143 }
159144 }
160145
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+
161161 // It's not guaranteed that there are no interior null bytes, hence no Deref to CStr.
162162 // This does not include the null byte at the end!
163163 impl Deref for $string {
@@ -200,15 +200,39 @@ macro_rules! string_impl {
200200
201201 impl Eq for $string { }
202202
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( ) ) ;
206208 }
207209 }
208210
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)
212236 }
213237 }
214238
@@ -218,6 +242,12 @@ macro_rules! string_impl {
218242 }
219243 }
220244
245+ impl PartialEq for $string {
246+ fn eq( & self , other: & Self ) -> bool {
247+ self . deref( ) . eq( other. deref( ) )
248+ }
249+ }
250+
221251 impl PartialOrd for $string {
222252 fn partial_cmp( & self , other: & Self ) -> Option <Ordering > {
223253 self . deref( ) . partial_cmp( other. deref( ) )
@@ -503,4 +533,64 @@ mod tests {
503533 s. as_str ( ) . try_into ( ) . unwrap ( )
504534 }
505535 }
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+ }
506596}
0 commit comments