Skip to content
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