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