@@ -4,15 +4,15 @@ use crate::translate::*;
4
4
use crate :: types:: { StaticType , Type } ;
5
5
use crate :: value:: { FromValue , ToValue } ;
6
6
use crate :: Value ;
7
- use std:: borrow:: Borrow ;
7
+ use std:: borrow:: { Borrow , Cow } ;
8
8
use std:: cmp:: Ordering ;
9
- use std:: ffi:: { CStr , CString , OsStr } ;
9
+ use std:: ffi:: { CStr , CString , OsStr , OsString } ;
10
10
use std:: fmt;
11
11
use std:: hash;
12
12
use std:: mem;
13
13
use std:: ops:: Deref ;
14
14
use std:: os:: raw:: { c_char, c_void} ;
15
- use std:: path:: Path ;
15
+ use std:: path:: { Path , PathBuf } ;
16
16
use std:: ptr;
17
17
use std:: slice;
18
18
use std:: string:: String ;
@@ -327,6 +327,13 @@ impl<'a> TryFrom<&'a CStr> for &'a GStr {
327
327
}
328
328
}
329
329
330
+ impl < ' a > From < & ' a GStr > for Cow < ' a , GStr > {
331
+ #[ inline]
332
+ fn from ( s : & ' a GStr ) -> Self {
333
+ Cow :: Borrowed ( s)
334
+ }
335
+ }
336
+
330
337
impl PartialEq < GStr > for String {
331
338
fn eq ( & self , other : & GStr ) -> bool {
332
339
self . as_str ( ) == other. as_str ( )
@@ -1231,6 +1238,42 @@ impl From<GString> for Box<str> {
1231
1238
}
1232
1239
}
1233
1240
1241
+ impl From < GString > for Vec < u8 > {
1242
+ #[ inline]
1243
+ fn from ( value : GString ) -> Vec < u8 > {
1244
+ value. into_bytes_with_nul ( )
1245
+ }
1246
+ }
1247
+
1248
+ impl TryFrom < GString > for CString {
1249
+ type Error = GStringInteriorNulError < GString > ;
1250
+ #[ inline]
1251
+ fn try_from ( value : GString ) -> Result < Self , Self :: Error > {
1252
+ if let Some ( nul_pos) = memchr:: memchr ( 0 , value. as_bytes ( ) ) {
1253
+ return Err ( GStringInteriorNulError (
1254
+ value,
1255
+ GStrInteriorNulError ( nul_pos) ,
1256
+ ) ) ;
1257
+ }
1258
+ let v = value. into_bytes_with_nul ( ) ;
1259
+ Ok ( unsafe { CString :: from_vec_with_nul_unchecked ( v) } )
1260
+ }
1261
+ }
1262
+
1263
+ impl From < GString > for OsString {
1264
+ #[ inline]
1265
+ fn from ( s : GString ) -> Self {
1266
+ OsString :: from ( String :: from ( s) )
1267
+ }
1268
+ }
1269
+
1270
+ impl From < GString > for PathBuf {
1271
+ #[ inline]
1272
+ fn from ( s : GString ) -> Self {
1273
+ PathBuf :: from ( OsString :: from ( s) )
1274
+ }
1275
+ }
1276
+
1234
1277
impl From < String > for GString {
1235
1278
#[ inline]
1236
1279
fn from ( mut s : String ) -> Self {
@@ -1257,6 +1300,16 @@ impl From<Box<str>> for GString {
1257
1300
}
1258
1301
}
1259
1302
1303
+ impl < ' a > From < Cow < ' a , str > > for GString {
1304
+ #[ inline]
1305
+ fn from ( s : Cow < ' a , str > ) -> Self {
1306
+ match s {
1307
+ Cow :: Borrowed ( s) => Self :: from ( s) ,
1308
+ Cow :: Owned ( s) => Self :: from ( s) ,
1309
+ }
1310
+ }
1311
+ }
1312
+
1260
1313
impl From < & GStr > for GString {
1261
1314
#[ inline]
1262
1315
fn from ( s : & GStr ) -> GString {
@@ -1285,22 +1338,73 @@ impl From<&str> for GString {
1285
1338
}
1286
1339
}
1287
1340
1288
- impl From < CString > for GString {
1341
+ impl TryFrom < CString > for GString {
1342
+ type Error = GStringUtf8Error < CString > ;
1289
1343
#[ inline]
1290
- fn from ( s : CString ) -> Self {
1291
- // Moves the content of the CString
1292
- // Also check if it's valid UTF-8
1293
- let s = String :: from_utf8 ( s. into_bytes_with_nul ( ) ) . unwrap ( ) ;
1294
- Self ( Inner :: Native ( Some ( s. into_boxed_str ( ) ) ) )
1344
+ fn try_from ( value : CString ) -> Result < Self , Self :: Error > {
1345
+ if value. as_bytes ( ) . is_empty ( ) {
1346
+ Ok ( Self ( Inner :: Native ( None ) ) )
1347
+ } else {
1348
+ // Moves the content of the CString
1349
+ // Also check if it's valid UTF-8
1350
+ let s = String :: from_utf8 ( value. into_bytes_with_nul ( ) ) . map_err ( |e| {
1351
+ let err = e. utf8_error ( ) ;
1352
+ GStringUtf8Error (
1353
+ unsafe { CString :: from_vec_with_nul_unchecked ( e. into_bytes ( ) ) } ,
1354
+ err,
1355
+ )
1356
+ } ) ?;
1357
+ Ok ( Self ( Inner :: Native ( Some ( s. into ( ) ) ) ) )
1358
+ }
1295
1359
}
1296
1360
}
1297
1361
1298
- impl From < & CStr > for GString {
1362
+ impl TryFrom < OsString > for GString {
1363
+ type Error = GStringFromError < OsString > ;
1299
1364
#[ inline]
1300
- fn from ( c : & CStr ) -> Self {
1301
- // Creates a copy with the GLib allocator
1302
- // Also check if it's valid UTF-8
1303
- c. to_str ( ) . unwrap ( ) . into ( )
1365
+ fn try_from ( value : OsString ) -> Result < Self , Self :: Error > {
1366
+ Self :: from_string_checked ( value. into_string ( ) . map_err ( GStringFromError :: Unspecified ) ?)
1367
+ . map_err ( |e| GStringFromError :: from ( e) . convert ( OsString :: from) )
1368
+ }
1369
+ }
1370
+
1371
+ impl TryFrom < PathBuf > for GString {
1372
+ type Error = GStringFromError < PathBuf > ;
1373
+ #[ inline]
1374
+ fn try_from ( value : PathBuf ) -> Result < Self , Self :: Error > {
1375
+ GString :: try_from ( value. into_os_string ( ) ) . map_err ( |e| e. convert ( PathBuf :: from) )
1376
+ }
1377
+ }
1378
+
1379
+ impl TryFrom < & CStr > for GString {
1380
+ type Error = std:: str:: Utf8Error ;
1381
+ #[ inline]
1382
+ fn try_from ( value : & CStr ) -> Result < Self , Self :: Error > {
1383
+ // Check if it's valid UTF-8
1384
+ value. to_str ( ) ?;
1385
+ let gstr = unsafe { GStr :: from_utf8_with_nul_unchecked ( value. to_bytes_with_nul ( ) ) } ;
1386
+ Ok ( gstr. to_owned ( ) )
1387
+ }
1388
+ }
1389
+
1390
+ impl < ' a > From < Cow < ' a , GStr > > for GString {
1391
+ #[ inline]
1392
+ fn from ( s : Cow < ' a , GStr > ) -> Self {
1393
+ s. into_owned ( )
1394
+ }
1395
+ }
1396
+
1397
+ impl < ' a > From < GString > for Cow < ' a , GStr > {
1398
+ #[ inline]
1399
+ fn from ( s : GString ) -> Self {
1400
+ Cow :: Owned ( s)
1401
+ }
1402
+ }
1403
+
1404
+ impl < ' a > From < & ' a GString > for Cow < ' a , GStr > {
1405
+ #[ inline]
1406
+ fn from ( s : & ' a GString ) -> Self {
1407
+ Cow :: Borrowed ( s. as_gstr ( ) )
1304
1408
}
1305
1409
}
1306
1410
@@ -1698,7 +1802,7 @@ mod tests {
1698
1802
#[ test]
1699
1803
fn test_gstring_from_cstring ( ) {
1700
1804
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1701
- let gstring = GString :: from ( cstr) ;
1805
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1702
1806
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1703
1807
let foo: Box < str > = gstring. into ( ) ;
1704
1808
assert_eq ! ( foo. as_ref( ) , "foo" ) ;
@@ -1707,7 +1811,7 @@ mod tests {
1707
1811
#[ test]
1708
1812
fn test_string_from_gstring_from_cstring ( ) {
1709
1813
let cstr = CString :: new ( "foo" ) . unwrap ( ) ;
1710
- let gstring = GString :: from ( cstr) ;
1814
+ let gstring = GString :: try_from ( cstr) . unwrap ( ) ;
1711
1815
assert_eq ! ( gstring. as_str( ) , "foo" ) ;
1712
1816
let s = String :: from ( gstring) ;
1713
1817
assert_eq ! ( s, "foo" ) ;
0 commit comments