@@ -9,7 +9,6 @@ use std::any::TypeId;
9
9
use std:: borrow:: Cow ;
10
10
use std:: cell:: OnceCell ;
11
11
use std:: collections:: HashMap ;
12
- use std:: ffi:: CStr ;
13
12
use std:: fmt;
14
13
use std:: hash:: Hash ;
15
14
@@ -95,7 +94,7 @@ impl ClassId {
95
94
"In Godot < 4.4, class name must be ASCII: '{name}'"
96
95
) ;
97
96
98
- cache. insert_class_id ( ClassIdSource :: Owned ( name) , Some ( type_id) , false )
97
+ cache. insert_class_id ( ClassIdSource ( Cow :: Owned ( name) ) , Some ( type_id) , false )
99
98
}
100
99
101
100
/// Create a `ClassId` from a runtime string (for dynamic class names).
@@ -105,7 +104,7 @@ impl ClassId {
105
104
pub ( crate ) fn new_dynamic ( class_name : String ) -> Self {
106
105
let mut cache = CLASS_ID_CACHE . lock ( ) ;
107
106
108
- cache. insert_class_id ( ClassIdSource :: Owned ( class_name) , None , false )
107
+ cache. insert_class_id ( ClassIdSource ( Cow :: Owned ( class_name) ) , None , false )
109
108
}
110
109
111
110
// Test-only APIs.
@@ -127,37 +126,16 @@ impl ClassId {
127
126
Self { global_index : 0 }
128
127
}
129
128
130
- /// Create a new ASCII; expect to be unique. Internal, reserved for macros.
131
- #[ doc( hidden) ]
132
- pub fn __alloc_next_ascii ( class_name_cstr : & ' static CStr ) -> Self {
133
- let utf8 = class_name_cstr
134
- . to_str ( )
135
- . expect ( "class name is invalid UTF-8" ) ;
136
-
137
- assert ! (
138
- utf8. is_ascii( ) ,
139
- "ClassId::alloc_next_ascii() with non-ASCII Unicode string '{utf8}'"
140
- ) ;
141
-
142
- let source = ClassIdSource :: Borrowed ( class_name_cstr) ;
143
- let mut cache = CLASS_ID_CACHE . lock ( ) ;
144
- cache. insert_class_id ( source, None , true )
145
- }
146
-
147
129
/// Create a new Unicode entry; expect to be unique. Internal, reserved for macros.
148
130
#[ doc( hidden) ]
149
131
pub fn __alloc_next_unicode ( class_name_str : & ' static str ) -> Self {
132
+ #[ cfg( before_api = "4.4" ) ]
150
133
assert ! (
151
- cfg! ( since_api = "4.4" ) ,
134
+ class_name_str . is_ascii ( ) ,
152
135
"Before Godot 4.4, class names must be ASCII, but '{class_name_str}' is not.\n See https://github.com/godotengine/godot/pull/96501."
153
136
) ;
154
137
155
- assert ! (
156
- !class_name_str. is_ascii( ) ,
157
- "ClassId::__alloc_next_unicode() with ASCII string '{class_name_str}'"
158
- ) ;
159
-
160
- let source = ClassIdSource :: Owned ( class_name_str. to_owned ( ) ) ;
138
+ let source = ClassIdSource ( Cow :: Borrowed ( class_name_str) ) ;
161
139
let mut cache = CLASS_ID_CACHE . lock ( ) ;
162
140
cache. insert_class_id ( source, None , true )
163
141
}
@@ -206,15 +184,13 @@ impl ClassId {
206
184
207
185
impl fmt:: Display for ClassId {
208
186
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
209
- self . with_string_name ( |s| s . fmt ( f) )
187
+ self . to_cow_str ( ) . fmt ( f)
210
188
}
211
189
}
212
190
213
191
impl fmt:: Debug for ClassId {
214
192
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
215
- let cache = CLASS_ID_CACHE . lock ( ) ;
216
- let entry = cache. get_entry ( self . global_index as usize ) ;
217
- let name = entry. rust_str . as_cow_str ( ) ;
193
+ let name = self . to_cow_str ( ) ;
218
194
219
195
if name. is_empty ( ) {
220
196
write ! ( f, "ClassId(none)" )
@@ -224,10 +200,6 @@ impl fmt::Debug for ClassId {
224
200
}
225
201
}
226
202
227
- fn ascii_cstr_to_str ( cstr : & CStr ) -> & str {
228
- cstr. to_str ( ) . expect ( "should be validated ASCII" )
229
- }
230
-
231
203
// ----------------------------------------------------------------------------------------------------------------------------------------------
232
204
233
205
/// Entry in the class name cache.
@@ -247,31 +219,25 @@ impl ClassIdEntry {
247
219
}
248
220
249
221
fn none ( ) -> Self {
250
- Self :: new ( ClassIdSource :: Borrowed ( c"" ) )
222
+ Self :: new ( ClassIdSource ( Cow :: Borrowed ( "" ) ) )
251
223
}
252
224
}
253
225
254
226
// ----------------------------------------------------------------------------------------------------------------------------------------------
255
227
256
- /// `Cow`-like enum for class names, but with C strings as the borrowed variant.
257
- enum ClassIdSource {
258
- Owned ( String ) ,
259
- Borrowed ( & ' static CStr ) ,
260
- }
228
+ /// `Cow` for class names, with static strings as the borrowed variant.
229
+ struct ClassIdSource ( Cow < ' static , str > ) ;
261
230
262
231
impl ClassIdSource {
263
232
fn to_string_name ( & self ) -> StringName {
264
- match self {
265
- ClassIdSource :: Owned ( s) => StringName :: from ( s) ,
266
- ClassIdSource :: Borrowed ( cstr ) => StringName :: __cstr ( cstr ) ,
233
+ match & self . 0 {
234
+ Cow :: Owned ( s) => StringName :: from ( s) ,
235
+ Cow :: Borrowed ( str ) => StringName :: from ( * str ) ,
267
236
}
268
237
}
269
238
270
239
fn as_cow_str ( & self ) -> Cow < ' static , str > {
271
- match self {
272
- ClassIdSource :: Owned ( s) => Cow :: Owned ( s. clone ( ) ) ,
273
- ClassIdSource :: Borrowed ( cstr) => Cow :: Borrowed ( ascii_cstr_to_str ( cstr) ) ,
274
- }
240
+ self . 0 . clone ( )
275
241
}
276
242
}
277
243
// ----------------------------------------------------------------------------------------------------------------------------------------------
0 commit comments