Skip to content

Commit 164beb8

Browse files
bors[bot]mivort
andauthored
Merge #816
816: Expose GodotString formatting facility r=Bromeon a=lufterc This PR exposes `godot_string_format` API method to make built-in Godot string formatting available in GDNative API. It also adds a basic formatting in-engine test case. Co-authored-by: lufterc <[email protected]>
2 parents 5b8b36e + 3042768 commit 164beb8

File tree

1 file changed

+54
-1
lines changed

1 file changed

+54
-1
lines changed

gdnative-core/src/core_types/string.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::core_types::Variant;
12
use crate::object::NewRef;
23
use crate::private::get_api;
34
use crate::sys;
@@ -201,6 +202,41 @@ impl GodotString {
201202
unsafe { (get_api().godot_string_find_last)(&self.0, what.0) }
202203
}
203204

205+
/// Formats the string by replacing all occurrences of a key in the string with the
206+
/// corresponding value. The method can handle arrays or dictionaries for the key/value pairs.
207+
///
208+
/// Arrays can be used as key, index, or mixed style (see below examples). Order only matters
209+
/// when the index or mixed style of Array is used.
210+
///
211+
/// # Examples
212+
///
213+
/// ```no_run
214+
/// # use gdnative::prelude::*;
215+
/// // Array values, index style
216+
/// let template = GodotString::from("{0} {1}");
217+
/// let data = VariantArray::new();
218+
/// data.push("foo");
219+
/// data.push("bar");
220+
///
221+
/// let formatted = template.format(&data.into_shared().to_variant());
222+
/// godot_print!("{}", formatted); // "foo bar"
223+
/// ```
224+
///
225+
/// ```no_run
226+
/// # use gdnative::prelude::*;
227+
/// // Dictionary values
228+
/// let template = GodotString::from("foo {bar}");
229+
/// let data = Dictionary::new();
230+
/// data.insert("bar", "baz");
231+
///
232+
/// let formatted = template.format(&data.into_shared().to_variant());
233+
/// godot_print!("{}", formatted); // "foo baz"
234+
/// ```
235+
#[inline]
236+
pub fn format(&self, values: &Variant) -> Self {
237+
Self(unsafe { (get_api().godot_string_format)(&self.0, &values.0) })
238+
}
239+
204240
/// Returns the internal ffi representation of the string and consumes
205241
/// the rust object without running the destructor.
206242
///
@@ -663,7 +699,7 @@ mod serialize {
663699
}
664700

665701
godot_test!(test_string {
666-
use crate::core_types::{GodotString, Variant, VariantType, ToVariant};
702+
use crate::core_types::{GodotString, Variant, VariantType, ToVariant, VariantArray, Dictionary};
667703

668704
let foo: GodotString = "foo".into();
669705
assert_eq!(foo.len(), 3);
@@ -708,4 +744,21 @@ godot_test!(test_string {
708744
}
709745

710746
assert_eq!(foo.to_utf8().as_str(), "foo");
747+
748+
let fmt_string = GodotString::from("foo {bar}");
749+
let fmt_data = Dictionary::new();
750+
fmt_data.insert("bar", "baz");
751+
752+
let fmt = fmt_string.format(&fmt_data.into_shared().to_variant());
753+
assert_eq!(fmt, GodotString::from("foo baz"));
754+
assert_eq!(fmt_string, GodotString::from("foo {bar}"));
755+
756+
let fmt_string2 = GodotString::from("{0} {1}");
757+
let fmt_data2 = VariantArray::new();
758+
fmt_data2.push("foo");
759+
fmt_data2.push("bar");
760+
761+
let fmt2 = fmt_string2.format(&fmt_data2.into_shared().to_variant());
762+
assert_eq!(fmt2, GodotString::from("foo bar"));
763+
assert_eq!(fmt_string2, GodotString::from("{0} {1}"));
711764
});

0 commit comments

Comments
 (0)