diff --git a/core/ustring.cpp b/core/ustring.cpp index 394c68516ae..db9a711a7b1 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -2776,6 +2776,78 @@ bool String::matchn(const String &p_wildcard) const { return _wildcard_match(p_wildcard.c_str(), c_str(), false); } +String String::format(const Variant &values, String placeholder) const { + + String new_string = String(this->ptr()); + + if (values.get_type() == Variant::ARRAY) { + Array values_arr = values; + + for (int i = 0; i < values_arr.size(); i++) { + String i_as_str = String::num_int64(i); + + if (values_arr[i].get_type() == Variant::ARRAY) { //Array in Array structure [["name","RobotGuy"],[0,"godot"],["strength",9000.91]] + Array value_arr = values_arr[i]; + + if (value_arr.size() == 2) { + Variant v_key = value_arr[0]; + String key; + + key = v_key.get_construct_string(); + if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") { + key = key.substr(1, key.length() - 2); + } + + Variant v_val = value_arr[1]; + String val; + val = v_val.get_construct_string(); + + if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + val = val.substr(1, val.length() - 2); + } + + new_string = new_string.replacen(placeholder.replace("_", key), val); + } else { + ERR_PRINT(String("STRING.format Inner Array size != 2 ").ascii().get_data()); + } + } else { //Array structure ["RobotGuy","Logis","rookie"] + Variant v_val = values_arr[i]; + String val; + val = v_val.get_construct_string(); + + if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + val = val.substr(1, val.length() - 2); + } + + new_string = new_string.replacen(placeholder.replace("_", i_as_str), val); + } + } + } else if (values.get_type() == Variant::DICTIONARY) { + Dictionary d = values; + List keys; + d.get_key_list(&keys); + + for (List::Element *E = keys.front(); E; E = E->next()) { + String key = E->get().get_construct_string(); + String val = d[E->get()].get_construct_string(); + + if (key.left(1) == "\"" && key.right(key.length() - 1) == "\"") { + key = key.substr(1, key.length() - 2); + } + + if (val.left(1) == "\"" && val.right(val.length() - 1) == "\"") { + val = val.substr(1, val.length() - 2); + } + + new_string = new_string.replacen(placeholder.replace("_", key), val); + } + } else { + ERR_PRINT(String("Invalid type: use Array or Dictionary.").ascii().get_data()); + } + + return new_string; +} + String String::replace(String p_key, String p_with) const { String new_string; diff --git a/core/ustring.h b/core/ustring.h index 5516675de17..c6b894143f4 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -120,6 +120,7 @@ public: bool is_subsequence_ofi(const String &p_string) const; Vector bigrams() const; float similarity(const String &p_string) const; + String format(const Variant& values, String placeholder = "{_}") const; String replace_first(String p_key, String p_with) const; String replace(String p_key, String p_with) const; String replacen(String p_key, String p_with) const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 01a3b4a1b03..3d11f6577d9 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -241,6 +241,7 @@ struct _VariantCall { VCALL_LOCALMEM1R(String, is_subsequence_ofi); VCALL_LOCALMEM0R(String, bigrams); VCALL_LOCALMEM1R(String, similarity); + VCALL_LOCALMEM2R(String, format); VCALL_LOCALMEM2R(String, replace); VCALL_LOCALMEM2R(String, replacen); VCALL_LOCALMEM2R(String, insert); @@ -1317,6 +1318,7 @@ void register_variant_methods() { ADDFUNC0(STRING, STRING_ARRAY, String, bigrams, varray()); ADDFUNC1(STRING, REAL, String, similarity, STRING, "text", varray()); + ADDFUNC2(STRING, STRING, String, format, NIL, "values", STRING, "placeholder", varray("{_}")); ADDFUNC2(STRING, STRING, String, replace, STRING, "what", STRING, "forwhat", varray()); ADDFUNC2(STRING, STRING, String, replacen, STRING, "what", STRING, "forwhat", varray()); ADDFUNC2(STRING, STRING, String, insert, INT, "pos", STRING, "what", varray());