Skip to content

Commit 9d5cb63

Browse files
committed
StringName: remove From impl for &'static CStr
1 parent 6588315 commit 9d5cb63

File tree

7 files changed

+36
-43
lines changed

7 files changed

+36
-43
lines changed

godot-codegen/src/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn c_str(string: &str) -> Literal {
4141
pub fn make_string_name(identifier: &str) -> TokenStream {
4242
let lit = c_str(identifier);
4343

44-
quote! { StringName::from(#lit) }
44+
quote! { StringName::__static_cstr(#lit) }
4545
}
4646

4747
pub fn make_sname_ptr(identifier: &str) -> TokenStream {

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

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* License, v. 2.0. If a copy of the MPL was not distributed with this
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
7+
78
use std::fmt;
89

910
use godot_ffi as sys;
@@ -248,6 +249,37 @@ impl StringName {
248249
pub fn as_inner(&self) -> inner::InnerStringName<'_> {
249250
inner::InnerStringName::from_outer(self)
250251
}
252+
253+
/// Creates a `StringName` from a static ASCII/Latin-1 `c"string"`.
254+
///
255+
/// This avoids unnecessary copies and allocations and directly uses the backing buffer. Useful for literals.
256+
///
257+
/// Note that while Latin-1 encoding is the most common encoding for c-strings, it isn't a requirement. So if your c-string
258+
/// uses a different encoding (e.g. UTF-8), it is possible that some characters will not show up as expected.
259+
///
260+
/// # Safety
261+
/// `c_str` must be a static c-string that remains valid for the entire program duration.
262+
///
263+
/// # Example
264+
/// ```no_run
265+
/// use godot::builtin::StringName;
266+
///
267+
/// // '±' is a Latin-1 character with codepoint 0xB1. Note that this is not UTF-8, where it would need two bytes.
268+
/// let sname = StringName::__static_cstr(c"\xb1 Latin-1 string");
269+
/// ```
270+
#[doc(hidden)] // Private for now. Needs API discussion, also regarding overlap with try_from_cstr().
271+
pub fn __static_cstr(c_str: &'static std::ffi::CStr) -> Self {
272+
// SAFETY: c_str is nul-terminated and remains valid for entire program duration.
273+
unsafe {
274+
Self::new_with_string_uninit(|ptr| {
275+
sys::interface_fn!(string_name_new_with_latin1_chars)(
276+
ptr,
277+
c_str.as_ptr(),
278+
sys::conv::SYS_TRUE, // p_is_static
279+
)
280+
})
281+
}
282+
}
251283
}
252284

253285
// SAFETY:
@@ -354,35 +386,6 @@ impl From<&NodePath> for StringName {
354386
}
355387
}
356388

357-
impl From<&std::ffi::CStr> for StringName {
358-
/// Creates a `StringName` from a ASCII/Latin-1 `c"string"`.
359-
///
360-
/// This avoids unnecessary copies and allocations and directly uses the backing buffer. Useful for literals.
361-
///
362-
/// Note that while Latin-1 encoding is the most common encoding for c-strings, it isn't a requirement. So if your c-string
363-
/// uses a different encoding (e.g. UTF-8), it is possible that some characters will not show up as expected.
364-
///
365-
/// # Example
366-
/// ```no_run
367-
/// use godot::builtin::StringName;
368-
///
369-
/// // '±' is a Latin-1 character with codepoint 0xB1. Note that this is not UTF-8, where it would need two bytes.
370-
/// let sname = StringName::from(c"\xb1 Latin-1 string");
371-
/// ```
372-
fn from(c_str: &std::ffi::CStr) -> Self {
373-
// SAFETY: c_str is nul-terminated and remains valid for entire program duration.
374-
unsafe {
375-
Self::new_with_string_uninit(|ptr| {
376-
sys::interface_fn!(string_name_new_with_latin1_chars)(
377-
ptr,
378-
c_str.as_ptr(),
379-
sys::conv::SYS_FALSE, // p_is_static
380-
)
381-
})
382-
}
383-
}
384-
}
385-
386389
// ----------------------------------------------------------------------------------------------------------------------------------------------
387390
// Ordering
388391

godot-core/src/meta/args/as_arg.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8-
use std::ffi::CStr;
9-
108
use crate::builtin::{GString, NodePath, StringName, Variant};
119
use crate::meta::sealed::Sealed;
1210
use crate::meta::traits::{GodotFfiVariant, GodotNullableFfi};
@@ -562,12 +560,6 @@ impl AsArg<StringName> for &String {
562560
}
563561
}
564562

565-
impl AsArg<StringName> for &'static CStr {
566-
fn into_arg<'arg>(self) -> CowArg<'arg, StringName> {
567-
CowArg::Owned(StringName::from(self))
568-
}
569-
}
570-
571563
// ----------------------------------------------------------------------------------------------------------------------------------------------
572564
// NodePath
573565

godot-core/src/meta/class_id.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl ClassIdSource {
263263
fn to_string_name(&self) -> StringName {
264264
match self {
265265
ClassIdSource::Owned(s) => StringName::from(s),
266-
ClassIdSource::Borrowed(cstr) => StringName::from(*cstr),
266+
ClassIdSource::Borrowed(cstr) => StringName::__cstr(cstr),
267267
}
268268
}
269269

godot-macros/src/class/data_models/inherent_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ fn add_virtual_script_call(
459459

460460
let code = quote! {
461461
let object_ptr = #object_ptr;
462-
let method_sname = ::godot::builtin::StringName::from(#method_name_cstr);
462+
let method_sname = ::godot::builtin::StringName::__static_cstr(#method_name_cstr);
463463
let method_sname_ptr = method_sname.string_sys();
464464
let has_virtual_override = unsafe { ::godot::private::has_virtual_script_method(object_ptr, method_sname_ptr) };
465465

itest/rust/src/builtin_tests/convert_test.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ fn strings_as_arg() {
344344
// Note: CowArg is an internal type.
345345

346346
let str = "GodotRocks";
347-
let cstr = c"GodotRocks";
348347
let gstring = GString::from("GodotRocks");
349348
let sname = StringName::from("GodotRocks");
350349
let npath = NodePath::from("GodotRocks");
@@ -355,7 +354,6 @@ fn strings_as_arg() {
355354
assert_eq!(as_gstr_arg(npath.arg()), CowArg::Owned(gstring.clone()));
356355

357356
assert_eq!(as_sname_arg(str), CowArg::Owned(sname.clone()));
358-
assert_eq!(as_sname_arg(cstr), CowArg::Owned(sname.clone()));
359357
assert_eq!(as_sname_arg(&sname), CowArg::Borrowed(&sname));
360358
assert_eq!(as_sname_arg(gstring.arg()), CowArg::Owned(sname.clone()));
361359
assert_eq!(as_sname_arg(npath.arg()), CowArg::Owned(sname.clone()));

itest/rust/src/builtin_tests/string/string_name_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn string_name_from_cstr() {
127127
];
128128

129129
for (bytes, string) in cases.into_iter() {
130-
let a = StringName::from(bytes);
130+
let a = StringName::__static_cstr(bytes);
131131
let b = StringName::from(string);
132132

133133
assert_eq!(a, b);

0 commit comments

Comments
 (0)