@@ -82,7 +82,7 @@ impl GString {
8282
8383impl Clone for GString {
8484 fn clone ( & self ) -> GString {
85- self . as_str ( ) . into ( )
85+ self . as_str ( ) . try_into ( ) . unwrap ( )
8686 }
8787}
8888
@@ -247,70 +247,68 @@ impl From<GString> for Box<str> {
247247 }
248248}
249249
250- impl From < String > for GString {
250+ impl TryFrom < String > for GString {
251+ type Error = std:: ffi:: NulError ;
251252 #[ inline]
252- fn from ( s : String ) -> Self {
253+ fn try_from ( s : String ) -> Result < Self , Self :: Error > {
253254 // Moves the content of the String
254- unsafe {
255- // No check for valid UTF-8 here
256- let cstr = CString :: from_vec_unchecked ( s. into_bytes ( ) ) ;
257- GString ( Inner :: Native ( Some ( cstr) ) )
258- }
255+ // Check for interior nul bytes
256+ let cstr = CString :: new ( s. into_bytes ( ) ) ?;
257+ Ok ( GString ( Inner :: Native ( Some ( cstr) ) ) )
259258 }
260259}
261260
262- impl From < Box < str > > for GString {
261+ impl TryFrom < Box < str > > for GString {
262+ type Error = std:: ffi:: NulError ;
263263 #[ inline]
264- fn from ( s : Box < str > ) -> Self {
264+ fn try_from ( s : Box < str > ) -> Result < Self , Self :: Error > {
265265 // Moves the content of the String
266- s. into_string ( ) . into ( )
266+ s. into_string ( ) . try_into ( )
267267 }
268268}
269269
270- impl < ' a > From < & ' a str > for GString {
270+ impl TryFrom < & str > for GString {
271+ type Error = std:: ffi:: NulError ;
271272 #[ inline]
272- fn from ( s : & ' a str ) -> Self {
273- // Allocates with the GLib allocator
274- unsafe {
275- // No check for valid UTF-8 here
276- let copy = ffi:: g_malloc ( s. len ( ) + 1 ) as * mut c_char ;
277- ptr:: copy_nonoverlapping ( s. as_ptr ( ) as * const c_char , copy, s. len ( ) + 1 ) ;
278- ptr:: write ( copy. add ( s. len ( ) ) , 0 ) ;
279-
280- GString ( Inner :: Foreign {
281- ptr : ptr:: NonNull :: new_unchecked ( copy) ,
282- len : s. len ( ) ,
283- } )
284- }
273+ fn try_from ( s : & str ) -> Result < Self , Self :: Error > {
274+ s. to_owned ( ) . try_into ( )
285275 }
286276}
287277
288- impl From < Vec < u8 > > for GString {
278+ #[ derive( thiserror:: Error , Debug ) ]
279+ pub enum GStringError {
280+ #[ error( "invalid UTF-8" ) ]
281+ Utf8 ( #[ from] std:: str:: Utf8Error ) ,
282+ #[ error( "interior nul bytes" ) ]
283+ Nul ( #[ from] std:: ffi:: NulError ) ,
284+ }
285+
286+ impl TryFrom < Vec < u8 > > for GString {
287+ type Error = GStringError ;
289288 #[ inline]
290- fn from ( s : Vec < u8 > ) -> Self {
289+ fn try_from ( s : Vec < u8 > ) -> Result < Self , Self :: Error > {
291290 // Moves the content of the Vec
292291 // Also check if it's valid UTF-8
293- let cstring = CString :: new ( s) . expect ( "CString::new failed" ) ;
294- cstring. into ( )
292+ let cstring = CString :: new ( s) ? ;
293+ Ok ( cstring. try_into ( ) ? )
295294 }
296295}
297296
298- impl From < CString > for GString {
299- # [ inline ]
300- fn from ( s : CString ) -> Self {
297+ impl TryFrom < CString > for GString {
298+ type Error = std :: str :: Utf8Error ;
299+ fn try_from ( s : CString ) -> Result < Self , Self :: Error > {
301300 // Moves the content of the CString
302301 // Also check if it's valid UTF-8
303- assert ! ( s. to_str( ) . is_ok ( ) ) ;
304- Self ( Inner :: Native ( Some ( s) ) )
302+ s. to_str ( ) ? ;
303+ Ok ( Self ( Inner :: Native ( Some ( s) ) ) )
305304 }
306305}
307306
308- impl < ' a > From < & ' a CStr > for GString {
307+ impl TryFrom < & CStr > for GString {
308+ type Error = std:: str:: Utf8Error ;
309309 #[ inline]
310- fn from ( c : & ' a CStr ) -> Self {
311- // Creates a copy with the GLib allocator
312- // Also check if it's valid UTF-8
313- c. to_str ( ) . unwrap ( ) . into ( )
310+ fn try_from ( c : & CStr ) -> Result < Self , Self :: Error > {
311+ c. to_owned ( ) . try_into ( )
314312 }
315313}
316314
@@ -361,7 +359,7 @@ impl FromGlibPtrNone<*const u8> for GString {
361359 assert ! ( !ptr. is_null( ) ) ;
362360 let cstr = CStr :: from_ptr ( ptr as * const _ ) ;
363361 // Also check if it's valid UTF-8
364- cstr. to_str ( ) . unwrap ( ) . into ( )
362+ cstr. try_into ( ) . unwrap ( )
365363 }
366364}
367365
@@ -493,16 +491,16 @@ impl<'a> ToGlibPtr<'a, *mut i8> for GString {
493491impl < ' a > FromGlibContainer < * const c_char , * const i8 > for GString {
494492 unsafe fn from_glib_none_num ( ptr : * const i8 , num : usize ) -> Self {
495493 if num == 0 || ptr. is_null ( ) {
496- return Self :: from ( "" ) ;
494+ return Self :: try_from ( "" ) . unwrap ( ) ;
497495 }
498496 let slice = slice:: from_raw_parts ( ptr as * const u8 , num) ;
499497 // Also check if it's valid UTF-8
500- std:: str:: from_utf8 ( slice) . unwrap ( ) . into ( )
498+ std:: str:: from_utf8 ( slice) . unwrap ( ) . try_into ( ) . unwrap ( )
501499 }
502500
503501 unsafe fn from_glib_container_num ( ptr : * const i8 , num : usize ) -> Self {
504502 if num == 0 || ptr. is_null ( ) {
505- return Self :: from ( "" ) ;
503+ return Self :: try_from ( "" ) . unwrap ( ) ;
506504 }
507505
508506 // Check if it's valid UTF-8
@@ -517,7 +515,7 @@ impl<'a> FromGlibContainer<*const c_char, *const i8> for GString {
517515
518516 unsafe fn from_glib_full_num ( ptr : * const i8 , num : usize ) -> Self {
519517 if num == 0 || ptr. is_null ( ) {
520- return Self :: from ( "" ) ;
518+ return Self :: try_from ( "" ) . unwrap ( ) ;
521519 }
522520
523521 // Check if it's valid UTF-8
@@ -596,7 +594,7 @@ unsafe impl<'a> crate::value::FromValue<'a> for GString {
596594 type Checker = crate :: value:: GenericValueTypeOrNoneChecker < Self > ;
597595
598596 unsafe fn from_value ( value : & ' a crate :: Value ) -> Self {
599- Self :: from ( <& str >:: from_value ( value) )
597+ Self :: try_from ( <& str >:: from_value ( value) ) . unwrap ( )
600598 }
601599}
602600
@@ -686,15 +684,15 @@ mod tests {
686684
687685 #[ test]
688686 fn test_gstring_from_str ( ) {
689- let gstring: GString = "foo" . into ( ) ;
687+ let gstring: GString = "foo" . try_into ( ) . unwrap ( ) ;
690688 assert_eq ! ( gstring. as_str( ) , "foo" ) ;
691689 let foo: Box < str > = gstring. into ( ) ;
692690 assert_eq ! ( foo. as_ref( ) , "foo" ) ;
693691 }
694692
695693 #[ test]
696694 fn test_string_from_gstring ( ) {
697- let gstring = GString :: from ( "foo" ) ;
695+ let gstring = GString :: try_from ( "foo" ) . unwrap ( ) ;
698696 assert_eq ! ( gstring. as_str( ) , "foo" ) ;
699697 let s = String :: from ( gstring) ;
700698 assert_eq ! ( s, "foo" ) ;
@@ -703,7 +701,7 @@ mod tests {
703701 #[ test]
704702 fn test_gstring_from_cstring ( ) {
705703 let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
706- let gstring = GString :: from ( cstr) ;
704+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
707705 assert_eq ! ( gstring. as_str( ) , "foo" ) ;
708706 let foo: Box < str > = gstring. into ( ) ;
709707 assert_eq ! ( foo. as_ref( ) , "foo" ) ;
@@ -712,7 +710,7 @@ mod tests {
712710 #[ test]
713711 fn test_string_from_gstring_from_cstring ( ) {
714712 let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
715- let gstring = GString :: from ( cstr) ;
713+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
716714 assert_eq ! ( gstring. as_str( ) , "foo" ) ;
717715 let s = String :: from ( gstring) ;
718716 assert_eq ! ( s, "foo" ) ;
@@ -721,7 +719,7 @@ mod tests {
721719 #[ test]
722720 fn test_vec_u8_to_gstring ( ) {
723721 let v: & [ u8 ] = b"foo" ;
724- let s: GString = Vec :: from ( v) . into ( ) ;
722+ let s: GString = Vec :: from ( v) . try_into ( ) . unwrap ( ) ;
725723 assert_eq ! ( s. as_str( ) , "foo" ) ;
726724 }
727725
@@ -754,11 +752,11 @@ mod tests {
754752 fn test_hashmap ( ) {
755753 use std:: collections:: HashMap ;
756754
757- let gstring = GString :: from ( "foo" ) ;
755+ let gstring = GString :: try_from ( "foo" ) . unwrap ( ) ;
758756 assert_eq ! ( gstring. as_str( ) , "foo" ) ;
759757 let mut h: HashMap < GString , i32 > = HashMap :: new ( ) ;
760758 h. insert ( gstring, 42 ) ;
761- let gstring: GString = "foo" . into ( ) ;
759+ let gstring: GString = "foo" . try_into ( ) . unwrap ( ) ;
762760 assert ! ( h. contains_key( & gstring) ) ;
763761 }
764762}
0 commit comments