@@ -573,6 +573,10 @@ impl<'a> ToGlibPtr<'a, *mut c_char> for GStr {
573
573
}
574
574
}
575
575
576
+ // size_of::<Inner>() minus two bytes for length and enum discriminant
577
+ const INLINE_LEN : usize =
578
+ mem:: size_of :: < Option < Box < str > > > ( ) + mem:: size_of :: < usize > ( ) - mem:: size_of :: < u8 > ( ) * 2 ;
579
+
576
580
// rustdoc-stripper-ignore-next
577
581
/// A type representing an owned, C-compatible, nul-terminated UTF-8 string.
578
582
///
@@ -609,6 +613,32 @@ impl GString {
609
613
Self ( Inner :: Native ( None ) )
610
614
}
611
615
// rustdoc-stripper-ignore-next
616
+ /// Formats an [`Arguments`](std::fmt::Arguments) into a [`GString`].
617
+ ///
618
+ /// This function is the same as [`std::fmt::format`], except it returns a [`GString`]. The
619
+ /// [`Arguments`](std::fmt::Arguments) instance can be created with the
620
+ /// [`format_args!`](std::format_args) macro.
621
+ ///
622
+ /// Please note that using [`gformat!`] might be preferable.
623
+ pub fn format ( args : fmt:: Arguments ) -> Self {
624
+ if let Some ( s) = args. as_str ( ) {
625
+ return Self :: from ( s) ;
626
+ }
627
+
628
+ let mut s = crate :: GStringBuilder :: default ( ) ;
629
+ fmt:: Write :: write_fmt ( & mut s, args) . unwrap ( ) ;
630
+ let s = mem:: ManuallyDrop :: new ( s) ;
631
+ if s. inner . str . is_null ( ) {
632
+ debug_assert_eq ! ( s. inner. allocated_len, 0 ) ;
633
+ GString :: new ( )
634
+ } else {
635
+ debug_assert ! ( s. inner. allocated_len > 0 && s. inner. len > 0 ) ;
636
+ GString ( Inner :: Foreign {
637
+ ptr : unsafe { ptr:: NonNull :: new_unchecked ( s. inner . str ) } ,
638
+ len : s. inner . len ,
639
+ } )
640
+ }
641
+ }
612
642
// rustdoc-stripper-ignore-next
613
643
/// Creates a GLib string by consuming a byte vector.
614
644
///
@@ -840,6 +870,16 @@ impl GString {
840
870
}
841
871
}
842
872
873
+ // rustdoc-stripper-ignore-next
874
+ /// Creates a [`GString`] using interpolation of runtime expressions.
875
+ ///
876
+ /// This macro is the same as [`std::format!`] except it returns a [`GString`]. It is faster than
877
+ /// creating a [`String`] and then converting it manually to a [`GString`].
878
+ #[ macro_export]
879
+ macro_rules! gformat {
880
+ ( $( $arg: tt) * ) => { GString :: format( std:: format_args!( $( $arg) * ) ) } ;
881
+ }
882
+
843
883
// rustdoc-stripper-ignore-next
844
884
/// Error type indicating that a buffer did not have a trailing nul-byte.
845
885
///
@@ -1869,4 +1909,10 @@ mod tests {
1869
1909
let gstring: GString = "foo" . into ( ) ;
1870
1910
assert ! ( h. contains_key( & gstring) ) ;
1871
1911
}
1912
+
1913
+ #[ test]
1914
+ fn gformat ( ) {
1915
+ let s = gformat ! ( "bla bla {} bla" , 123 ) ;
1916
+ assert_eq ! ( s, "bla bla 123 bla" ) ;
1917
+ }
1872
1918
}
0 commit comments