Skip to content

Commit 38385b7

Browse files
committed
GString::*cmp* functions (WIP)
1 parent 6c89d57 commit 38385b7

File tree

3 files changed

+84
-9
lines changed

3 files changed

+84
-9
lines changed

godot-codegen/src/special_cases/special_cases.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,6 @@ pub fn is_builtin_method_exposed(builtin_ty: &TyName, godot_method_name: &str) -
235235
// TODO maybe consider renaming "match_" -> "matches". The "*n" could technically be "*_n", but is probably OK.
236236

237237
// GString
238-
| ("String", "casecmp_to")
239-
| ("String", "nocasecmp_to")
240-
| ("String", "naturalcasecmp_to")
241-
| ("String", "naturalnocasecmp_to")
242-
| ("String", "filecasecmp_to")
243-
| ("String", "filenocasecmp_to")
244238
| ("String", "get_slice")
245239
| ("String", "get_slicec")
246240
| ("String", "get_slice_count")

godot-core/src/builtin/string/gstring.rs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ use std::convert::Infallible;
99
use std::ffi::c_char;
1010
use std::fmt::Write;
1111
use std::str::FromStr;
12-
use std::{fmt, ops};
12+
use std::{cmp, fmt, ops};
1313

1414
use godot_ffi as sys;
1515
use sys::types::OpaqueString;
1616
use sys::{ffi_methods, interface_fn, GodotFfi};
1717

1818
use crate::builtin::{inner, NodePath, StringName, Variant};
1919
use crate::meta;
20+
use crate::meta::AsArg;
2021

2122
/// Godot's reference counted string type.
2223
///
@@ -80,6 +81,7 @@ impl GString {
8081
/// Number of characters in the string.
8182
///
8283
/// _Godot equivalent: `length`_
84+
#[doc(alias = "length")]
8385
pub fn len(&self) -> usize {
8486
self.as_inner().length().try_into().unwrap()
8587
}
@@ -130,11 +132,81 @@ impl GString {
130132
pub fn format_with_placeholder(
131133
&self,
132134
array_or_dict: &Variant,
133-
placeholder: impl meta::AsArg<GString>,
135+
placeholder: impl AsArg<GString>,
134136
) -> Self {
135137
self.as_inner().format(array_or_dict, placeholder)
136138
}
137139

140+
/// Case-sensitive, lexicographic comparison to another string.
141+
///
142+
/// Returns the `Ordering` relation of `self` towards `to`. Ordering is determined by the Unicode code points of each string, which roughly
143+
/// matches the alphabetical order.
144+
///
145+
/// See also [`nocasecmp_to()`](Self::nocasecmp_to), [`naturalcasecmp_to()`](Self::naturalcasecmp_to), [`filecasecmp_to()`](Self::filecasecmp_to).
146+
pub fn casecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
147+
sys::i64_to_ordering(self.as_inner().casecmp_to(to))
148+
}
149+
150+
/// Case-**insensitive**, lexicographic comparison to another string.
151+
///
152+
/// Returns the `Ordering` relation of `self` towards `to`. Ordering is determined by the Unicode code points of each string, which roughly
153+
/// matches the alphabetical order.
154+
///
155+
/// See also [`casecmp_to()`](Self::casecmp_to), [`naturalcasecmp_to()`](Self::naturalcasecmp_to), [`filecasecmp_to()`](Self::filecasecmp_to).
156+
pub fn nocasecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
157+
sys::i64_to_ordering(self.as_inner().nocasecmp_to(to))
158+
}
159+
160+
/// Case-sensitive, **natural-order** comparison to another string.
161+
///
162+
/// Returns the `Ordering` relation of `self` towards `to`. Ordering is determined by the Unicode code points of each string, which roughly
163+
/// matches the alphabetical order.
164+
///
165+
/// When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected,
166+
/// instead of the single digit's value. A sorted sequence of numbered strings will be `["1", "2", "3", ...]`, not `["1", "10", "2", "3", ...]`.
167+
///
168+
/// With different string lengths, returns `Ordering::Greater` if this string is longer than the `to` string, or `Ordering::Less` if shorter.
169+
///
170+
/// See also [`casecmp_to()`](Self::casecmp_to), [`naturalnocasecmp_to()`](Self::naturalnocasecmp_to), [`filecasecmp_to()`](Self::filecasecmp_to).
171+
pub fn naturalcasecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
172+
sys::i64_to_ordering(self.as_inner().naturalcasecmp_to(to))
173+
}
174+
175+
/// Case-insensitive, **natural-order** comparison to another string.
176+
///
177+
/// Returns the `Ordering` relation of `self` towards `to`. Ordering is determined by the Unicode code points of each string, which roughly
178+
/// matches the alphabetical order.
179+
///
180+
/// When used for sorting, natural order comparison orders sequences of numbers by the combined value of each digit as is often expected,
181+
/// instead of the single digit's value. A sorted sequence of numbered strings will be `["1", "2", "3", ...]`, not `["1", "10", "2", "3", ...]`.
182+
///
183+
/// With different string lengths, returns `Ordering::Greater` if this string is longer than the `to` string, or `Ordering::Less` if shorter.
184+
///
185+
/// See also [`casecmp_to()`](Self::casecmp_to), [`naturalcasecmp_to()`](Self::naturalcasecmp_to), [`filecasecmp_to()`](Self::filecasecmp_to).
186+
pub fn naturalnocasecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
187+
sys::i64_to_ordering(self.as_inner().naturalnocasecmp_to(to))
188+
}
189+
190+
/// Case-sensitive, filename-oriented comparison to another string.
191+
///
192+
/// Like [`naturalcasecmp_to()`][Self::naturalcasecmp_to], but prioritizes strings that begin with periods (`.`) and underscores (`_`) before
193+
/// any other character. Useful when sorting folders or file names.
194+
///
195+
/// See also [`casecmp_to()`](Self::casecmp_to), [`naturalcasecmp_to()`](Self::naturalcasecmp_to), [`filenocasecmp_to()`](Self::filenocasecmp_to).
196+
pub fn filecasecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
197+
sys::i64_to_ordering(self.as_inner().filecasecmp_to(to))
198+
}
199+
200+
/// Case-insensitive, filename-oriented comparison to another string.
201+
///
202+
/// Like [`naturalnocasecmp_to()`][Self::naturalnocasecmp_to], but prioritizes strings that begin with periods (`.`) and underscores (`_`) before
203+
/// any other character. Useful when sorting folders or file names.
204+
///
205+
/// See also [`casecmp_to()`](Self::casecmp_to), [`naturalcasecmp_to()`](Self::naturalcasecmp_to), [`filecasecmp_to()`](Self::filecasecmp_to).
206+
pub fn filenocasecmp_to(&self, to: impl AsArg<GString>) -> cmp::Ordering {
207+
sys::i64_to_ordering(self.as_inner().filenocasecmp_to(to))
208+
}
209+
138210
ffi_methods! {
139211
type sys::GDExtensionStringPtr = *mut Self;
140212

@@ -184,7 +256,7 @@ impl GString {
184256
}
185257

186258
meta::declare_arg_method! {
187-
/// Use as argument for an [`impl AsArg<StringName|NodePath>`][crate::meta::AsArg] parameter.
259+
/// Use as argument for an [`impl AsArg<StringName|NodePath>`][crate::AsArg] parameter.
188260
///
189261
/// This is a convenient way to convert arguments of similar string types.
190262
///

godot-ffi/src/toolbox.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ where
180180
result
181181
}
182182

183+
pub fn i64_to_ordering(value: i64) -> std::cmp::Ordering {
184+
match value {
185+
-1 => std::cmp::Ordering::Less,
186+
0 => std::cmp::Ordering::Equal,
187+
1 => std::cmp::Ordering::Greater,
188+
_ => panic!("cannot convert value {value} to cmp::Ordering"),
189+
}
190+
}
191+
183192
/*
184193
pub fn unqualified_type_name<T>() -> &'static str {
185194
let type_name = std::any::type_name::<T>();

0 commit comments

Comments
 (0)