@@ -271,6 +271,7 @@ impl GStr {
271
271
Ok ( ( ) )
272
272
}
273
273
}
274
+ pub const NONE : Option < & ' static GStr > = None ;
274
275
}
275
276
276
277
// rustdoc-stripper-ignore-next
@@ -1870,6 +1871,92 @@ impl From<Vec<GString>> for Value {
1870
1871
impl_from_glib_container_as_vec_string ! ( GString , * const c_char) ;
1871
1872
impl_from_glib_container_as_vec_string ! ( GString , * mut c_char) ;
1872
1873
1874
+ // rustdoc-stripper-ignore-next
1875
+ /// A trait to accept both <code>&[str]</code> or <code>&[GStr]</code> as an argument.
1876
+ pub trait IntoGStr {
1877
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T ;
1878
+ }
1879
+
1880
+ impl IntoGStr for & GStr {
1881
+ #[ inline]
1882
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1883
+ f ( self )
1884
+ }
1885
+ }
1886
+
1887
+ impl IntoGStr for GString {
1888
+ #[ inline]
1889
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1890
+ f ( self . as_gstr ( ) )
1891
+ }
1892
+ }
1893
+
1894
+ impl IntoGStr for & GString {
1895
+ #[ inline]
1896
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1897
+ f ( self . as_gstr ( ) )
1898
+ }
1899
+ }
1900
+
1901
+ // Limit borrowed from rust std CStr optimization:
1902
+ // https://github.com/rust-lang/rust/blob/master/library/std/src/sys/common/small_c_string.rs#L10
1903
+ const MAX_STACK_ALLOCATION : usize = 384 ;
1904
+
1905
+ impl IntoGStr for & str {
1906
+ #[ inline]
1907
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1908
+ if self . len ( ) < MAX_STACK_ALLOCATION {
1909
+ let mut s = mem:: MaybeUninit :: < [ u8 ; MAX_STACK_ALLOCATION ] > :: uninit ( ) ;
1910
+ let ptr = s. as_mut_ptr ( ) as * mut u8 ;
1911
+ let gs = unsafe {
1912
+ ptr:: copy_nonoverlapping ( self . as_ptr ( ) , ptr, self . len ( ) ) ;
1913
+ ptr. add ( self . len ( ) ) . write ( 0 ) ;
1914
+ GStr :: from_utf8_with_nul_unchecked ( slice:: from_raw_parts ( ptr, self . len ( ) + 1 ) )
1915
+ } ;
1916
+ f ( gs)
1917
+ } else {
1918
+ f ( GString :: from ( self ) . as_gstr ( ) )
1919
+ }
1920
+ }
1921
+ }
1922
+
1923
+ impl IntoGStr for String {
1924
+ #[ inline]
1925
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1926
+ if self . len ( ) < MAX_STACK_ALLOCATION {
1927
+ self . as_str ( ) . run_with_gstr ( f)
1928
+ } else {
1929
+ f ( GString :: from ( self ) . as_gstr ( ) )
1930
+ }
1931
+ }
1932
+ }
1933
+
1934
+ impl IntoGStr for & String {
1935
+ #[ inline]
1936
+ fn run_with_gstr < T , F : FnOnce ( & GStr ) -> T > ( self , f : F ) -> T {
1937
+ self . as_str ( ) . run_with_gstr ( f)
1938
+ }
1939
+ }
1940
+
1941
+ pub const NONE_STR : Option < & ' static str > = None ;
1942
+
1943
+ // rustdoc-stripper-ignore-next
1944
+ /// A trait to accept both <code>[Option]<&[str]></code> or <code>[Option]<&[GStr]></code> as
1945
+ /// an argument.
1946
+ pub trait IntoOptionalGStr {
1947
+ fn run_with_gstr < T , F : FnOnce ( Option < & GStr > ) -> T > ( self , f : F ) -> T ;
1948
+ }
1949
+
1950
+ impl < S : IntoGStr > IntoOptionalGStr for Option < S > {
1951
+ #[ inline]
1952
+ fn run_with_gstr < T , F : FnOnce ( Option < & GStr > ) -> T > ( self , f : F ) -> T {
1953
+ match self {
1954
+ Some ( t) => t. run_with_gstr ( |s| f ( Some ( s) ) ) ,
1955
+ None => f ( None ) ,
1956
+ }
1957
+ }
1958
+ }
1959
+
1873
1960
#[ cfg( test) ]
1874
1961
#[ allow( clippy:: disallowed_names) ]
1875
1962
mod tests {
0 commit comments