@@ -271,6 +271,7 @@ impl GStr {
271271 Ok ( ( ) )
272272 }
273273 }
274+ pub const NONE : Option < & ' static GStr > = None ;
274275}
275276
276277// rustdoc-stripper-ignore-next
@@ -1870,6 +1871,92 @@ impl From<Vec<GString>> for Value {
18701871impl_from_glib_container_as_vec_string ! ( GString , * const c_char) ;
18711872impl_from_glib_container_as_vec_string ! ( GString , * mut c_char) ;
18721873
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+
18731960#[ cfg( test) ]
18741961#[ allow( clippy:: disallowed_names) ]
18751962mod tests {
0 commit comments