@@ -123,6 +123,20 @@ impl std::ops::Deref for StrV {
123123 }
124124}
125125
126+ impl AsRef < CStrV > for StrV {
127+ #[ inline]
128+ fn as_ref ( & self ) -> & CStrV {
129+ self . into ( )
130+ }
131+ }
132+
133+ impl std:: borrow:: Borrow < CStrV > for StrV {
134+ #[ inline]
135+ fn borrow ( & self ) -> & CStrV {
136+ self . into ( )
137+ }
138+ }
139+
126140impl std:: iter:: Extend < GString > for StrV {
127141 #[ inline]
128142 fn extend < I : IntoIterator < Item = GString > > ( & mut self , iter : I ) {
@@ -1359,6 +1373,49 @@ impl<const N: usize> IntoStrV for [&'_ String; N] {
13591373 }
13601374}
13611375
1376+ // rustdoc-stripper-ignore-next
1377+ /// Representation of a borrowed `NULL`-terminated C array of `NULL`-terminated UTF-8 strings.
1378+ ///
1379+ /// It can be constructed safely from a `&StrV` and unsafely from a pointer to a C array.
1380+ /// This type is very similar to `[GStringPtr]`, but with one added constraint: the underlying C array must be `NULL`-terminated.
1381+ #[ repr( transparent) ]
1382+ pub struct CStrV {
1383+ inner : [ GStringPtr ] ,
1384+ }
1385+
1386+ impl CStrV {
1387+ // rustdoc-stripper-ignore-next
1388+ /// Borrows a C array.
1389+ /// # Safety
1390+ ///
1391+ /// The provided pointer **must** be `NULL`-terminated. It is undefined behavior to
1392+ /// pass a pointer that does not uphold this condition.
1393+ #[ inline]
1394+ pub unsafe fn from_glib_borrow < ' a > ( ptr : * const * const c_char ) -> & ' a CStrV {
1395+ let slice = StrV :: from_glib_borrow ( ptr) ;
1396+ & * ( slice as * const [ GStringPtr ] as * const CStrV )
1397+ }
1398+
1399+ // rustdoc-stripper-ignore-next
1400+ /// Returns the underlying pointer.
1401+ ///
1402+ /// This is guaranteed to be nul-terminated.
1403+ #[ inline]
1404+ pub const fn as_ptr ( & self ) -> * const * const c_char {
1405+ self . inner . as_ptr ( ) as * const * const _
1406+ }
1407+ }
1408+
1409+ impl < ' a > From < & ' a StrV > for & ' a CStrV {
1410+ fn from ( value : & ' a StrV ) -> Self {
1411+ let slice = value. as_slice ( ) ;
1412+ // Safety: `&StrV` is a null-terminated C array of nul-terminated UTF-8 strings,
1413+ // therefore `&StrV::as_slice()` return a a null-terminated slice of nul-terminated UTF-8 strings,
1414+ // thus it is safe to convert it to `&CStr`.
1415+ unsafe { & * ( slice as * const [ GStringPtr ] as * const CStrV ) }
1416+ }
1417+ }
1418+
13621419#[ cfg( test) ]
13631420mod test {
13641421 use super :: * ;
0 commit comments