@@ -82,7 +82,7 @@ impl GString {
82
82
83
83
impl Clone for GString {
84
84
fn clone ( & self ) -> GString {
85
- self . as_str ( ) . into ( )
85
+ self . as_str ( ) . try_into ( ) . unwrap ( )
86
86
}
87
87
}
88
88
@@ -247,70 +247,68 @@ impl From<GString> for Box<str> {
247
247
}
248
248
}
249
249
250
- impl From < String > for GString {
250
+ impl TryFrom < String > for GString {
251
+ type Error = std:: ffi:: NulError ;
251
252
#[ inline]
252
- fn from ( s : String ) -> Self {
253
+ fn try_from ( s : String ) -> Result < Self , Self :: Error > {
253
254
// 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) ) ) )
259
258
}
260
259
}
261
260
262
- impl From < Box < str > > for GString {
261
+ impl TryFrom < Box < str > > for GString {
262
+ type Error = std:: ffi:: NulError ;
263
263
#[ inline]
264
- fn from ( s : Box < str > ) -> Self {
264
+ fn try_from ( s : Box < str > ) -> Result < Self , Self :: Error > {
265
265
// Moves the content of the String
266
- s. into_string ( ) . into ( )
266
+ s. into_string ( ) . try_into ( )
267
267
}
268
268
}
269
269
270
- impl < ' a > From < & ' a str > for GString {
270
+ impl TryFrom < & str > for GString {
271
+ type Error = std:: ffi:: NulError ;
271
272
#[ 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 ( )
285
275
}
286
276
}
287
277
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 ;
289
288
#[ inline]
290
- fn from ( s : Vec < u8 > ) -> Self {
289
+ fn try_from ( s : Vec < u8 > ) -> Result < Self , Self :: Error > {
291
290
// Moves the content of the Vec
292
291
// 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 ( ) ? )
295
294
}
296
295
}
297
296
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 > {
301
300
// Moves the content of the CString
302
301
// 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) ) ) )
305
304
}
306
305
}
307
306
308
- impl < ' a > From < & ' a CStr > for GString {
307
+ impl TryFrom < & CStr > for GString {
308
+ type Error = std:: str:: Utf8Error ;
309
309
#[ 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 ( )
314
312
}
315
313
}
316
314
@@ -361,7 +359,7 @@ impl FromGlibPtrNone<*const u8> for GString {
361
359
assert ! ( !ptr. is_null( ) ) ;
362
360
let cstr = CStr :: from_ptr ( ptr as * const _ ) ;
363
361
// Also check if it's valid UTF-8
364
- cstr. to_str ( ) . unwrap ( ) . into ( )
362
+ cstr. try_into ( ) . unwrap ( )
365
363
}
366
364
}
367
365
@@ -493,16 +491,16 @@ impl<'a> ToGlibPtr<'a, *mut i8> for GString {
493
491
impl < ' a > FromGlibContainer < * const c_char , * const i8 > for GString {
494
492
unsafe fn from_glib_none_num ( ptr : * const i8 , num : usize ) -> Self {
495
493
if num == 0 || ptr. is_null ( ) {
496
- return Self :: from ( "" ) ;
494
+ return Self :: try_from ( "" ) . unwrap ( ) ;
497
495
}
498
496
let slice = slice:: from_raw_parts ( ptr as * const u8 , num) ;
499
497
// 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 ( )
501
499
}
502
500
503
501
unsafe fn from_glib_container_num ( ptr : * const i8 , num : usize ) -> Self {
504
502
if num == 0 || ptr. is_null ( ) {
505
- return Self :: from ( "" ) ;
503
+ return Self :: try_from ( "" ) . unwrap ( ) ;
506
504
}
507
505
508
506
// Check if it's valid UTF-8
@@ -517,7 +515,7 @@ impl<'a> FromGlibContainer<*const c_char, *const i8> for GString {
517
515
518
516
unsafe fn from_glib_full_num ( ptr : * const i8 , num : usize ) -> Self {
519
517
if num == 0 || ptr. is_null ( ) {
520
- return Self :: from ( "" ) ;
518
+ return Self :: try_from ( "" ) . unwrap ( ) ;
521
519
}
522
520
523
521
// Check if it's valid UTF-8
@@ -596,7 +594,7 @@ unsafe impl<'a> crate::value::FromValue<'a> for GString {
596
594
type Checker = crate :: value:: GenericValueTypeOrNoneChecker < Self > ;
597
595
598
596
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 ( )
600
598
}
601
599
}
602
600
@@ -686,15 +684,15 @@ mod tests {
686
684
687
685
#[ test]
688
686
fn test_gstring_from_str ( ) {
689
- let gstring: GString = "foo" . into ( ) ;
687
+ let gstring: GString = "foo" . try_into ( ) . unwrap ( ) ;
690
688
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
691
689
let foo: Box < str > = gstring. into ( ) ;
692
690
assert_eq ! ( foo. as_ref( ) , "foo" ) ;
693
691
}
694
692
695
693
#[ test]
696
694
fn test_string_from_gstring ( ) {
697
- let gstring = GString :: from ( "foo" ) ;
695
+ let gstring = GString :: try_from ( "foo" ) . unwrap ( ) ;
698
696
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
699
697
let s = String :: from ( gstring) ;
700
698
assert_eq ! ( s, "foo" ) ;
@@ -703,7 +701,7 @@ mod tests {
703
701
#[ test]
704
702
fn test_gstring_from_cstring ( ) {
705
703
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
706
- let gstring = GString :: from ( cstr) ;
704
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
707
705
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
708
706
let foo: Box < str > = gstring. into ( ) ;
709
707
assert_eq ! ( foo. as_ref( ) , "foo" ) ;
@@ -712,7 +710,7 @@ mod tests {
712
710
#[ test]
713
711
fn test_string_from_gstring_from_cstring ( ) {
714
712
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
715
- let gstring = GString :: from ( cstr) ;
713
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
716
714
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
717
715
let s = String :: from ( gstring) ;
718
716
assert_eq ! ( s, "foo" ) ;
@@ -721,7 +719,7 @@ mod tests {
721
719
#[ test]
722
720
fn test_vec_u8_to_gstring ( ) {
723
721
let v: & [ u8 ] = b"foo" ;
724
- let s: GString = Vec :: from ( v) . into ( ) ;
722
+ let s: GString = Vec :: from ( v) . try_into ( ) . unwrap ( ) ;
725
723
assert_eq ! ( s. as_str( ) , "foo" ) ;
726
724
}
727
725
@@ -754,11 +752,11 @@ mod tests {
754
752
fn test_hashmap ( ) {
755
753
use std:: collections:: HashMap ;
756
754
757
- let gstring = GString :: from ( "foo" ) ;
755
+ let gstring = GString :: try_from ( "foo" ) . unwrap ( ) ;
758
756
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
759
757
let mut h: HashMap < GString , i32 > = HashMap :: new ( ) ;
760
758
h. insert ( gstring, 42 ) ;
761
- let gstring: GString = "foo" . into ( ) ;
759
+ let gstring: GString = "foo" . try_into ( ) . unwrap ( ) ;
762
760
assert ! ( h. contains_key( & gstring) ) ;
763
761
}
764
762
}
0 commit comments