Skip to content

Add many GString/StringName methods #980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 27, 2024
Merged
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Cutting-edge API docs of the `master` branch are available [here](https://godot-
- [v0.1.1](#v011), [v0.1.2](#v012), [v0.1.3](#v013)



## [v0.2.1](https://docs.rs/godot/0.2.1)

_8 December 2024_
Expand Down
161 changes: 153 additions & 8 deletions godot-codegen/src/special_cases/special_cases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,166 @@ pub fn is_method_private(class_or_builtin_ty: &TyName, godot_method_name: &str)
pub fn is_builtin_method_exposed(builtin_ty: &TyName, godot_method_name: &str) -> bool {
match (builtin_ty.godot_ty.as_str(), godot_method_name) {
// GString
| ("String", "casecmp_to")
| ("String", "nocasecmp_to")
| ("String", "begins_with")
| ("String", "ends_with")
| ("String", "is_subsequence_of")
| ("String", "is_subsequence_ofn")
| ("String", "bigrams")
| ("String", "similarity")
| ("String", "replace")
| ("String", "replacen")
| ("String", "repeat")
| ("String", "reverse")
| ("String", "capitalize")
| ("String", "to_camel_case")
| ("String", "to_pascal_case")
| ("String", "to_snake_case")
| ("String", "split_floats")
| ("String", "join")
| ("String", "to_upper")
| ("String", "to_lower")
| ("String", "left")
| ("String", "right")
| ("String", "strip_edges")
| ("String", "strip_escapes")
| ("String", "lstrip")
| ("String", "rstrip")
| ("String", "get_extension")
| ("String", "get_basename")
| ("String", "path_join")
| ("String", "indent")
| ("String", "dedent")
| ("String", "md5_text")
| ("String", "sha1_text")
| ("String", "sha256_text")
| ("String", "md5_buffer")
| ("String", "sha1_buffer")
| ("String", "sha256_buffer")
| ("String", "is_empty")
| ("String", "contains")
| ("String", "containsn")
| ("String", "is_absolute_path")
| ("String", "is_relative_path")
| ("String", "simplify_path")
| ("String", "get_base_dir")
| ("String", "get_file")
| ("String", "xml_escape")
| ("String", "xml_unescape")
| ("String", "uri_encode")
| ("String", "uri_decode")
| ("String", "c_escape")
| ("String", "c_unescape")
| ("String", "json_escape")
| ("String", "validate_node_name")
| ("String", "validate_filename")
| ("String", "is_valid_identifier")
| ("String", "is_valid_int")
| ("String", "is_valid_float")
| ("String", "is_valid_hex_number")
| ("String", "is_valid_html_color")
| ("String", "is_valid_ip_address")
| ("String", "is_valid_filename")
| ("String", "to_int")
| ("String", "to_float")
| ("String", "hex_to_int")
| ("String", "bin_to_int")
| ("String", "trim_prefix")
| ("String", "trim_suffix")
| ("String", "to_ascii_buffer")
| ("String", "to_utf8_buffer")
| ("String", "to_utf16_buffer")
| ("String", "to_utf32_buffer")
| ("String", "hex_decode")
| ("String", "to_wchar_buffer")
| ("String", "num_scientific")
| ("String", "num")
| ("String", "num_int64")
| ("String", "num_uint64")
| ("String", "chr")
| ("String", "humanize_size")

// StringName
| ("StringName", "casecmp_to")
| ("StringName", "begins_with")
| ("StringName", "ends_with")
| ("StringName", "is_subsequence_of")
| ("StringName", "is_subsequence_ofn")
| ("StringName", "bigrams")
| ("StringName", "similarity")
| ("StringName", "replace")
| ("StringName", "replacen")
| ("StringName", "repeat")
| ("StringName", "reverse")
| ("StringName", "capitalize")
| ("StringName", "to_camel_case")
| ("StringName", "to_pascal_case")
| ("StringName", "to_snake_case")
| ("StringName", "split_floats")
| ("StringName", "join")
| ("StringName", "to_upper")
| ("StringName", "to_lower")
| ("StringName", "left")
| ("StringName", "right")
| ("StringName", "strip_edges")
| ("StringName", "strip_escapes")
| ("StringName", "lstrip")
| ("StringName", "rstrip")
| ("StringName", "get_extension")
| ("StringName", "get_basename")
| ("StringName", "path_join")
| ("StringName", "indent")
| ("StringName", "dedent")
| ("StringName", "md5_text")
| ("StringName", "sha1_text")
| ("StringName", "sha256_text")
| ("StringName", "md5_buffer")
| ("StringName", "sha1_buffer")
| ("StringName", "sha256_buffer")
| ("StringName", "is_empty")
| ("StringName", "contains")
| ("StringName", "containsn")
| ("StringName", "is_absolute_path")
| ("StringName", "is_relative_path")
| ("StringName", "simplify_path")
| ("StringName", "get_base_dir")
| ("StringName", "get_file")
| ("StringName", "xml_escape")
| ("StringName", "xml_unescape")
| ("StringName", "uri_encode")
| ("StringName", "uri_decode")
| ("StringName", "c_escape")
| ("StringName", "c_unescape")
| ("StringName", "json_escape")
| ("StringName", "validate_node_name")
| ("StringName", "validate_filename")
| ("StringName", "is_valid_identifier")
| ("StringName", "is_valid_int")
| ("StringName", "is_valid_float")
| ("StringName", "is_valid_hex_number")
| ("StringName", "is_valid_html_color")
| ("StringName", "is_valid_ip_address")
| ("StringName", "is_valid_filename")
| ("StringName", "to_int")
| ("StringName", "to_float")
| ("StringName", "hex_to_int")
| ("StringName", "bin_to_int")
| ("StringName", "trim_prefix")
| ("StringName", "trim_suffix")
| ("StringName", "to_ascii_buffer")
| ("StringName", "to_utf8_buffer")
| ("StringName", "to_utf16_buffer")
| ("StringName", "to_utf32_buffer")
| ("StringName", "hex_decode")
| ("StringName", "to_wchar_buffer")

// NodePath

// (add more builtin types below)

// Vector2i
| ("Vector2i", "clampi")
| ("Vector2i", "distance_squared_to")
| ("Vector2i", "distance_to")
| ("Vector2i", "maxi")
// Vector2i
| ("Vector2i", "clampi")
| ("Vector2i", "distance_squared_to")
| ("Vector2i", "distance_to")
| ("Vector2i", "maxi")
| ("Vector2i", "mini")
| ("Vector2i", "snappedi")

Expand Down
4 changes: 3 additions & 1 deletion godot-core/src/builtin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ pub mod iter {

/// Specialized types related to Godot's various string implementations.
pub mod strings {
pub use super::string::TransientStringNameOrd;
pub use super::string::{
ExGStringFind, ExGStringSplit, ExStringNameFind, ExStringNameSplit, TransientStringNameOrd,
};
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down
38 changes: 26 additions & 12 deletions godot-core/src/builtin/string/gstring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

use std::convert::Infallible;
use std::ffi::c_char;
use std::fmt;
use std::fmt::Write;
use std::{convert::Infallible, ffi::c_char, fmt, str::FromStr};

use godot_ffi as sys;
use sys::types::OpaqueString;
use sys::{ffi_methods, interface_fn, GodotFfi};

use crate::builtin::{inner, NodePath, StringName};
use crate::builtin::{inner, NodePath, StringName, Variant};
use crate::meta::AsArg;
use crate::{impl_shared_string_api, meta};

/// Godot's reference counted string type.
///
Expand Down Expand Up @@ -56,6 +60,10 @@ use crate::builtin::{inner, NodePath, StringName};
/// | General purpose | **`GString`** |
/// | Interned names | [`StringName`][crate::builtin::StringName] |
/// | Scene-node paths | [`NodePath`][crate::builtin::NodePath] |
///
/// # Godot docs
///
/// [`String` (stable)](https://docs.godotengine.org/en/stable/classes/class_string.html)
#[doc(alias = "String")]
// #[repr] is needed on GString itself rather than the opaque field, because PackedStringArray::as_slice() relies on a packed representation.
#[repr(transparent)]
Expand All @@ -64,19 +72,19 @@ pub struct GString {
}

impl GString {
/// Construct a new empty GString.
/// Construct a new empty `GString`.
pub fn new() -> Self {
Self::default()
}

/// Number of characters in the string.
///
/// _Godot equivalent: `length`_
#[doc(alias = "length")]
pub fn len(&self) -> usize {
self.as_inner().length().try_into().unwrap()
}

pub fn is_empty(&self) -> bool {
self.as_inner().is_empty()
}

/// Returns a 32-bit integer hash value representing the string.
pub fn hash(&self) -> u32 {
self.as_inner()
Expand All @@ -85,7 +93,7 @@ impl GString {
.expect("Godot hashes are uint32_t")
}

/// Gets the UTF-32 character slice from a [`GString`].
/// Gets the UTF-32 character slice from a `GString`.
pub fn chars(&self) -> &[char] {
// SAFETY: Godot 4.1 ensures valid UTF-32, making interpreting as char slice safe.
// See https://github.com/godotengine/godot/pull/74760.
Expand All @@ -94,7 +102,7 @@ impl GString {
let len = interface_fn!(string_to_utf32_chars)(s, std::ptr::null_mut(), 0);
let ptr = interface_fn!(string_operator_index_const)(s, 0);

// Even when len == 0, from_raw_parts requires ptr != 0
// Even when len == 0, from_raw_parts requires ptr != null.
if ptr.is_null() {
return &[];
}
Expand Down Expand Up @@ -151,7 +159,7 @@ impl GString {
self.move_return_ptr(dst, sys::PtrcallType::Standard);
}

crate::meta::declare_arg_method! {
meta::declare_arg_method! {
/// Use as argument for an [`impl AsArg<StringName|NodePath>`][crate::meta::AsArg] parameter.
///
/// This is a convenient way to convert arguments of similar string types.
Expand Down Expand Up @@ -192,7 +200,7 @@ unsafe impl GodotFfi for GString {
ffi_methods! { type sys::GDExtensionTypePtr = *mut Self; .. }
}

crate::meta::impl_godot_as_self!(GString);
meta::impl_godot_as_self!(GString);

impl_builtin_traits! {
for GString {
Expand All @@ -205,6 +213,12 @@ impl_builtin_traits! {
}
}

impl_shared_string_api! {
builtin: GString,
find_builder: ExGStringFind,
split_builder: ExGStringSplit,
}

impl fmt::Display for GString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for ch in self.chars() {
Expand Down Expand Up @@ -301,7 +315,7 @@ impl From<GString> for String {
}
}

impl FromStr for GString {
impl std::str::FromStr for GString {
type Err = Infallible;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Expand Down
Loading
Loading