@@ -248,6 +248,7 @@ impl GStr {
248
248
Ok ( ( ) )
249
249
}
250
250
}
251
+ pub const NONE : Option < & ' static GStr > = None ;
251
252
}
252
253
253
254
// rustdoc-stripper-ignore-next
@@ -1793,6 +1794,92 @@ impl From<Vec<GString>> for Value {
1793
1794
impl_from_glib_container_as_vec_string ! ( GString , * const c_char) ;
1794
1795
impl_from_glib_container_as_vec_string ! ( GString , * mut c_char) ;
1795
1796
1797
+ // rustdoc-stripper-ignore-next
1798
+ /// A trait to accept both <code>&[str]</code> or <code>&[GStr]</code> as an argument.
1799
+ pub trait IntoGStr {
1800
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T ;
1801
+ }
1802
+
1803
+ impl IntoGStr for & GStr {
1804
+ #[ inline]
1805
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1806
+ f ( self )
1807
+ }
1808
+ }
1809
+
1810
+ impl IntoGStr for GString {
1811
+ #[ inline]
1812
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1813
+ f ( self . as_gstr ( ) )
1814
+ }
1815
+ }
1816
+
1817
+ impl IntoGStr for & GString {
1818
+ #[ inline]
1819
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1820
+ f ( self . as_gstr ( ) )
1821
+ }
1822
+ }
1823
+
1824
+ // Limit borrowed from rust std CStr optimization:
1825
+ // https://github.com/rust-lang/rust/blob/master/library/std/src/sys/common/small_c_string.rs#L10
1826
+ const MAX_STACK_ALLOCATION : usize = 384 ;
1827
+
1828
+ impl IntoGStr for & str {
1829
+ #[ inline]
1830
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1831
+ if self . len ( ) < MAX_STACK_ALLOCATION {
1832
+ let mut s = mem:: MaybeUninit :: < [ u8 ; MAX_STACK_ALLOCATION ] > :: uninit ( ) ;
1833
+ let ptr = s. as_mut_ptr ( ) as * mut u8 ;
1834
+ let gs = unsafe {
1835
+ ptr:: copy_nonoverlapping ( self . as_ptr ( ) , ptr, self . len ( ) ) ;
1836
+ ptr. add ( self . len ( ) ) . write ( 0 ) ;
1837
+ GStr :: from_utf8_with_nul_unchecked ( slice:: from_raw_parts ( ptr, self . len ( ) + 1 ) )
1838
+ } ;
1839
+ f ( gs)
1840
+ } else {
1841
+ f ( GString :: from ( self ) . as_gstr ( ) )
1842
+ }
1843
+ }
1844
+ }
1845
+
1846
+ impl IntoGStr for String {
1847
+ #[ inline]
1848
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1849
+ if self . len ( ) < MAX_STACK_ALLOCATION {
1850
+ self . as_str ( ) . run_with_gstr ( f)
1851
+ } else {
1852
+ f ( GString :: from ( self ) . as_gstr ( ) )
1853
+ }
1854
+ }
1855
+ }
1856
+
1857
+ impl IntoGStr for & String {
1858
+ #[ inline]
1859
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1860
+ self . as_str ( ) . run_with_gstr ( f)
1861
+ }
1862
+ }
1863
+
1864
+ pub const NONE_STR : Option < & ' static str > = None ;
1865
+
1866
+ // rustdoc-stripper-ignore-next
1867
+ /// A trait to accept both <code>[Option]<&[str]></code> or <code>[Option]<&[GStr]></code> as
1868
+ /// an argument.
1869
+ pub trait IntoOptionalGStr {
1870
+ fn run_with_gstr < T , F : FnOnce ( Option < & GStr > ) -> T > ( self , f : F ) -> T ;
1871
+ }
1872
+
1873
+ impl < S : IntoGStr > IntoOptionalGStr for Option < S > {
1874
+ #[ inline]
1875
+ fn run_with_gstr < T , F : FnOnce ( Option < & GStr > ) -> T > ( self , f : F ) -> T {
1876
+ match self {
1877
+ Some ( t) => t. run_with_gstr ( |s| f ( Some ( s) ) ) ,
1878
+ None => f ( None ) ,
1879
+ }
1880
+ }
1881
+ }
1882
+
1796
1883
#[ cfg( test) ]
1797
1884
#[ allow( clippy:: disallowed_names) ]
1798
1885
mod tests {
0 commit comments