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, mem,
8
8
ops:: Deref ,
9
9
os:: raw:: { c_char, c_void} ,
10
- path:: Path ,
10
+ path:: { Path , PathBuf } ,
11
11
ptr, slice,
12
12
} ;
13
13
@@ -1274,6 +1274,42 @@ impl From<GString> for Box<str> {
1274
1274
}
1275
1275
}
1276
1276
1277
+ impl From < GString > for Vec < u8 > {
1278
+ #[ inline]
1279
+ fn from ( value : GString ) -> Vec < u8 > {
1280
+ value. into_bytes_with_nul ( )
1281
+ }
1282
+ }
1283
+
1284
+ impl TryFrom < GString > for CString {
1285
+ type Error = GStringInteriorNulError < GString > ;
1286
+ #[ inline]
1287
+ fn try_from ( value : GString ) -> Result < Self , Self :: Error > {
1288
+ if let Some ( nul_pos) = memchr:: memchr ( 0 , value. as_bytes ( ) ) {
1289
+ return Err ( GStringInteriorNulError (
1290
+ value,
1291
+ GStrInteriorNulError ( nul_pos) ,
1292
+ ) ) ;
1293
+ }
1294
+ let v = value. into_bytes_with_nul ( ) ;
1295
+ Ok ( unsafe { CString :: from_vec_with_nul_unchecked ( v) } )
1296
+ }
1297
+ }
1298
+
1299
+ impl From < GString > for OsString {
1300
+ #[ inline]
1301
+ fn from ( s : GString ) -> Self {
1302
+ OsString :: from ( String :: from ( s) )
1303
+ }
1304
+ }
1305
+
1306
+ impl From < GString > for PathBuf {
1307
+ #[ inline]
1308
+ fn from ( s : GString ) -> Self {
1309
+ PathBuf :: from ( OsString :: from ( s) )
1310
+ }
1311
+ }
1312
+
1277
1313
impl From < String > for GString {
1278
1314
#[ inline]
1279
1315
fn from ( mut s : String ) -> Self {
@@ -1300,6 +1336,16 @@ impl From<Box<str>> for GString {
1300
1336
}
1301
1337
}
1302
1338
1339
+ impl < ' a > From < Cow < ' a , str > > for GString {
1340
+ #[ inline]
1341
+ fn from ( s : Cow < ' a , str > ) -> Self {
1342
+ match s {
1343
+ Cow :: Borrowed ( s) => Self :: from ( s) ,
1344
+ Cow :: Owned ( s) => Self :: from ( s) ,
1345
+ }
1346
+ }
1347
+ }
1348
+
1303
1349
impl From < & GStr > for GString {
1304
1350
#[ inline]
1305
1351
fn from ( s : & GStr ) -> GString {
@@ -1328,22 +1374,66 @@ impl From<&str> for GString {
1328
1374
}
1329
1375
}
1330
1376
1331
- impl From < CString > for GString {
1377
+ impl TryFrom < CString > for GString {
1378
+ type Error = GStringUtf8Error < CString > ;
1332
1379
#[ inline]
1333
- fn from ( s : CString ) -> Self {
1334
- // Moves the content of the CString
1335
- // Also check if it's valid UTF-8
1336
- let s = String :: from_utf8 ( s. into_bytes_with_nul ( ) ) . unwrap ( ) ;
1337
- Self ( Inner :: Native ( Some ( s. into_boxed_str ( ) ) ) )
1380
+ fn try_from ( value : CString ) -> Result < Self , Self :: Error > {
1381
+ if value. as_bytes ( ) . is_empty ( ) {
1382
+ Ok ( Self ( Inner :: Native ( None ) ) )
1383
+ } else {
1384
+ // Moves the content of the CString
1385
+ // Also check if it's valid UTF-8
1386
+ let s = String :: from_utf8 ( value. into_bytes_with_nul ( ) ) . map_err ( |e| {
1387
+ let err = e. utf8_error ( ) ;
1388
+ GStringUtf8Error (
1389
+ unsafe { CString :: from_vec_with_nul_unchecked ( e. into_bytes ( ) ) } ,
1390
+ err,
1391
+ )
1392
+ } ) ?;
1393
+ Ok ( Self ( Inner :: Native ( Some ( s. into ( ) ) ) ) )
1394
+ }
1338
1395
}
1339
1396
}
1340
1397
1341
- impl From < & CStr > for GString {
1398
+ impl TryFrom < OsString > for GString {
1399
+ type Error = GStringFromError < OsString > ;
1342
1400
#[ inline]
1343
- fn from ( c : & CStr ) -> Self {
1344
- // Creates a copy with the GLib allocator
1345
- // Also check if it's valid UTF-8
1346
- c. to_str ( ) . unwrap ( ) . into ( )
1401
+ fn try_from ( value : OsString ) -> Result < Self , Self :: Error > {
1402
+ Self :: from_string_checked ( value. into_string ( ) . map_err ( GStringFromError :: Unspecified ) ?)
1403
+ . map_err ( |e| GStringFromError :: from ( e) . convert ( OsString :: from) )
1404
+ }
1405
+ }
1406
+
1407
+ impl TryFrom < PathBuf > for GString {
1408
+ type Error = GStringFromError < PathBuf > ;
1409
+ #[ inline]
1410
+ fn try_from ( value : PathBuf ) -> Result < Self , Self :: Error > {
1411
+ GString :: try_from ( value. into_os_string ( ) ) . map_err ( |e| e. convert ( PathBuf :: from) )
1412
+ }
1413
+ }
1414
+
1415
+ impl TryFrom < & CStr > for GString {
1416
+ type Error = std:: str:: Utf8Error ;
1417
+ #[ inline]
1418
+ fn try_from ( value : & CStr ) -> Result < Self , Self :: Error > {
1419
+ // Check if it's valid UTF-8
1420
+ value. to_str ( ) ?;
1421
+ let gstr = unsafe { GStr :: from_utf8_with_nul_unchecked ( value. to_bytes_with_nul ( ) ) } ;
1422
+ Ok ( gstr. to_owned ( ) )
1423
+ }
1424
+ }
1425
+
1426
+ impl < ' a > From < Cow < ' a , GStr > > for GString {
1427
+ #[ inline]
1428
+ fn from ( s : Cow < ' a , GStr > ) -> Self {
1429
+ s. into_owned ( )
1430
+ }
1431
+ }
1432
+
1433
+ impl < ' a > From < & ' a GString > for Cow < ' a , GStr > {
1434
+ #[ inline]
1435
+ fn from ( s : & ' a GString ) -> Self {
1436
+ Cow :: Borrowed ( s. as_gstr ( ) )
1347
1437
}
1348
1438
}
1349
1439
@@ -1785,7 +1875,7 @@ mod tests {
1785
1875
#[ test]
1786
1876
fn test_gstring_from_cstring ( ) {
1787
1877
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1788
- let gstring = GString :: from ( cstr) ;
1878
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1789
1879
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1790
1880
let foo: Box < str > = gstring. into ( ) ;
1791
1881
assert_eq ! ( foo. as_ref( ) , "foo" ) ;
@@ -1794,7 +1884,7 @@ mod tests {
1794
1884
#[ test]
1795
1885
fn test_string_from_gstring_from_cstring ( ) {
1796
1886
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1797
- let gstring = GString :: from ( cstr) ;
1887
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1798
1888
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1799
1889
let s = String :: from ( gstring) ;
1800
1890
assert_eq ! ( s, "foo" ) ;
0 commit comments