3
3
use std:: {
4
4
borrow:: { Borrow , Cow } ,
5
5
cmp:: Ordering ,
6
- ffi:: { CStr , CString , OsStr } ,
6
+ ffi:: { CStr , CString , OsStr , OsString } ,
7
7
fmt, hash,
8
8
marker:: PhantomData ,
9
9
mem,
10
10
ops:: Deref ,
11
11
os:: raw:: { c_char, c_void} ,
12
- path:: Path ,
12
+ path:: { Path , PathBuf } ,
13
13
ptr, slice,
14
14
} ;
15
15
@@ -1282,6 +1282,42 @@ impl From<GString> for Box<str> {
1282
1282
}
1283
1283
}
1284
1284
1285
+ impl From < GString > for Vec < u8 > {
1286
+ #[ inline]
1287
+ fn from ( value : GString ) -> Vec < u8 > {
1288
+ value. into_bytes_with_nul ( )
1289
+ }
1290
+ }
1291
+
1292
+ impl TryFrom < GString > for CString {
1293
+ type Error = GStringInteriorNulError < GString > ;
1294
+ #[ inline]
1295
+ fn try_from ( value : GString ) -> Result < Self , Self :: Error > {
1296
+ if let Some ( nul_pos) = memchr:: memchr ( 0 , value. as_bytes ( ) ) {
1297
+ return Err ( GStringInteriorNulError (
1298
+ value,
1299
+ GStrInteriorNulError ( nul_pos) ,
1300
+ ) ) ;
1301
+ }
1302
+ let v = value. into_bytes_with_nul ( ) ;
1303
+ Ok ( unsafe { CString :: from_vec_with_nul_unchecked ( v) } )
1304
+ }
1305
+ }
1306
+
1307
+ impl From < GString > for OsString {
1308
+ #[ inline]
1309
+ fn from ( s : GString ) -> Self {
1310
+ OsString :: from ( String :: from ( s) )
1311
+ }
1312
+ }
1313
+
1314
+ impl From < GString > for PathBuf {
1315
+ #[ inline]
1316
+ fn from ( s : GString ) -> Self {
1317
+ PathBuf :: from ( OsString :: from ( s) )
1318
+ }
1319
+ }
1320
+
1285
1321
impl From < String > for GString {
1286
1322
#[ inline]
1287
1323
fn from ( mut s : String ) -> Self {
@@ -1308,6 +1344,16 @@ impl From<Box<str>> for GString {
1308
1344
}
1309
1345
}
1310
1346
1347
+ impl < ' a > From < Cow < ' a , str > > for GString {
1348
+ #[ inline]
1349
+ fn from ( s : Cow < ' a , str > ) -> Self {
1350
+ match s {
1351
+ Cow :: Borrowed ( s) => Self :: from ( s) ,
1352
+ Cow :: Owned ( s) => Self :: from ( s) ,
1353
+ }
1354
+ }
1355
+ }
1356
+
1311
1357
impl From < & GStr > for GString {
1312
1358
#[ inline]
1313
1359
fn from ( s : & GStr ) -> GString {
@@ -1336,22 +1382,66 @@ impl From<&str> for GString {
1336
1382
}
1337
1383
}
1338
1384
1339
- impl From < CString > for GString {
1385
+ impl TryFrom < CString > for GString {
1386
+ type Error = GStringUtf8Error < CString > ;
1340
1387
#[ inline]
1341
- fn from ( s : CString ) -> Self {
1342
- // Moves the content of the CString
1343
- // Also check if it's valid UTF-8
1344
- let s = String :: from_utf8 ( s. into_bytes_with_nul ( ) ) . unwrap ( ) ;
1345
- Self ( Inner :: Native ( Some ( s. into_boxed_str ( ) ) ) )
1388
+ fn try_from ( value : CString ) -> Result < Self , Self :: Error > {
1389
+ if value. as_bytes ( ) . is_empty ( ) {
1390
+ Ok ( Self ( Inner :: Native ( None ) ) )
1391
+ } else {
1392
+ // Moves the content of the CString
1393
+ // Also check if it's valid UTF-8
1394
+ let s = String :: from_utf8 ( value. into_bytes_with_nul ( ) ) . map_err ( |e| {
1395
+ let err = e. utf8_error ( ) ;
1396
+ GStringUtf8Error (
1397
+ unsafe { CString :: from_vec_with_nul_unchecked ( e. into_bytes ( ) ) } ,
1398
+ err,
1399
+ )
1400
+ } ) ?;
1401
+ Ok ( Self ( Inner :: Native ( Some ( s. into ( ) ) ) ) )
1402
+ }
1346
1403
}
1347
1404
}
1348
1405
1349
- impl From < & CStr > for GString {
1406
+ impl TryFrom < OsString > for GString {
1407
+ type Error = GStringFromError < OsString > ;
1350
1408
#[ inline]
1351
- fn from ( c : & CStr ) -> Self {
1352
- // Creates a copy with the GLib allocator
1353
- // Also check if it's valid UTF-8
1354
- c. to_str ( ) . unwrap ( ) . into ( )
1409
+ fn try_from ( value : OsString ) -> Result < Self , Self :: Error > {
1410
+ Self :: from_string_checked ( value. into_string ( ) . map_err ( GStringFromError :: Unspecified ) ?)
1411
+ . map_err ( |e| GStringFromError :: from ( e) . convert ( OsString :: from) )
1412
+ }
1413
+ }
1414
+
1415
+ impl TryFrom < PathBuf > for GString {
1416
+ type Error = GStringFromError < PathBuf > ;
1417
+ #[ inline]
1418
+ fn try_from ( value : PathBuf ) -> Result < Self , Self :: Error > {
1419
+ GString :: try_from ( value. into_os_string ( ) ) . map_err ( |e| e. convert ( PathBuf :: from) )
1420
+ }
1421
+ }
1422
+
1423
+ impl TryFrom < & CStr > for GString {
1424
+ type Error = std:: str:: Utf8Error ;
1425
+ #[ inline]
1426
+ fn try_from ( value : & CStr ) -> Result < Self , Self :: Error > {
1427
+ // Check if it's valid UTF-8
1428
+ value. to_str ( ) ?;
1429
+ let gstr = unsafe { GStr :: from_utf8_with_nul_unchecked ( value. to_bytes_with_nul ( ) ) } ;
1430
+ Ok ( gstr. to_owned ( ) )
1431
+ }
1432
+ }
1433
+
1434
+ impl < ' a > From < Cow < ' a , GStr > > for GString {
1435
+ #[ inline]
1436
+ fn from ( s : Cow < ' a , GStr > ) -> Self {
1437
+ s. into_owned ( )
1438
+ }
1439
+ }
1440
+
1441
+ impl < ' a > From < & ' a GString > for Cow < ' a , GStr > {
1442
+ #[ inline]
1443
+ fn from ( s : & ' a GString ) -> Self {
1444
+ Cow :: Borrowed ( s. as_gstr ( ) )
1355
1445
}
1356
1446
}
1357
1447
@@ -1793,7 +1883,7 @@ mod tests {
1793
1883
#[ test]
1794
1884
fn test_gstring_from_cstring ( ) {
1795
1885
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1796
- let gstring = GString :: from ( cstr) ;
1886
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1797
1887
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1798
1888
let foo: Box < str > = gstring. into ( ) ;
1799
1889
assert_eq ! ( foo. as_ref( ) , "foo" ) ;
@@ -1802,7 +1892,7 @@ mod tests {
1802
1892
#[ test]
1803
1893
fn test_string_from_gstring_from_cstring ( ) {
1804
1894
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1805
- let gstring = GString :: from ( cstr) ;
1895
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1806
1896
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1807
1897
let s = String :: from ( gstring) ;
1808
1898
assert_eq ! ( s, "foo" ) ;
0 commit comments