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