@@ -131,7 +131,7 @@ impl FromGodot for sys::VariantOperator {
131
131
// Scalars
132
132
133
133
macro_rules! impl_godot_scalar {
134
- ( $T: ty as $Via: ty, $err: path $ ( , $param_metadata: expr) ? ) => {
134
+ ( $T: ty as $Via: ty, $err: path, $param_metadata: expr) => {
135
135
impl GodotType for $T {
136
136
type Ffi = $Via;
137
137
@@ -144,40 +144,20 @@ macro_rules! impl_godot_scalar {
144
144
}
145
145
146
146
fn try_from_ffi( ffi: Self :: Ffi ) -> Result <Self , ConvertError > {
147
- Self :: try_from( ffi) . map_err( |_| $err. into_error( ffi) )
147
+ Self :: try_from( ffi) . map_err( |_rust_err| {
148
+ // rust_err is something like "out of range integral type conversion attempted", not adding extra information.
149
+ // TODO consider passing value into error message, but how thread-safely? don't eagerly convert to string.
150
+ $err. into_error( ffi)
151
+ } )
148
152
}
149
153
150
- $(
151
- fn param_metadata( ) -> sys:: GDExtensionClassMethodArgumentMetadata {
152
- $param_metadata
153
- }
154
- ) ?
155
-
156
- fn godot_type_name( ) -> String {
157
- <$Via as GodotType >:: godot_type_name( )
158
- }
159
- }
160
-
161
- impl ArrayElement for $T { }
162
-
163
- impl GodotConvert for $T {
164
- type Via = $T;
165
- }
166
-
167
- impl ToGodot for $T {
168
- fn to_godot( & self ) -> Self :: Via {
169
- * self
170
- }
154
+ impl_godot_scalar!( @shared_fns; $Via, $param_metadata) ;
171
155
}
172
156
173
- impl FromGodot for $T {
174
- fn try_from_godot( via: Self :: Via ) -> Result <Self , ConvertError > {
175
- Ok ( via)
176
- }
177
- }
157
+ impl_godot_scalar!( @shared_traits; $T) ;
178
158
} ;
179
159
180
- ( $T: ty as $Via: ty $ ( , $param_metadata: expr) ? ; lossy) => {
160
+ ( $T: ty as $Via: ty, $param_metadata: expr; lossy) => {
181
161
impl GodotType for $T {
182
162
type Ffi = $Via;
183
163
@@ -189,21 +169,27 @@ macro_rules! impl_godot_scalar {
189
169
self as $Via
190
170
}
191
171
192
- fn try_from_ffi( ffi: Self :: Ffi ) -> Result <Self , ConvertError > {
172
+ fn try_from_ffi( ffi: Self :: Ffi ) -> Result <Self , ConvertError > {
193
173
Ok ( ffi as $T)
194
174
}
195
175
196
- $(
197
- fn param_metadata( ) -> sys:: GDExtensionClassMethodArgumentMetadata {
198
- $param_metadata
199
- }
200
- ) ?
176
+ impl_godot_scalar!( @shared_fns; $Via, $param_metadata) ;
177
+ }
201
178
202
- fn godot_type_name( ) -> String {
203
- <$Via as GodotType >:: godot_type_name( )
204
- }
179
+ impl_godot_scalar!( @shared_traits; $T) ;
180
+ } ;
181
+
182
+ ( @shared_fns; $Via: ty, $param_metadata: expr) => {
183
+ fn param_metadata( ) -> sys:: GDExtensionClassMethodArgumentMetadata {
184
+ $param_metadata
185
+ }
186
+
187
+ fn godot_type_name( ) -> String {
188
+ <$Via as GodotType >:: godot_type_name( )
205
189
}
190
+ } ;
206
191
192
+ ( @shared_traits; $T: ty) => {
207
193
impl ArrayElement for $T { }
208
194
209
195
impl GodotConvert for $T {
@@ -231,47 +217,100 @@ impl_godot_as_self!(f64);
231
217
impl_godot_as_self ! ( ( ) ) ;
232
218
233
219
// Also implements ArrayElement.
234
- impl_godot_scalar ! (
235
- i32 as i64 ,
236
- crate :: builtin:: meta:: FromFfiError :: I32 ,
237
- sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32
238
- ) ;
239
- impl_godot_scalar ! (
240
- i16 as i64 ,
241
- crate :: builtin:: meta:: FromFfiError :: I16 ,
242
- sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16
243
- ) ;
244
220
impl_godot_scalar ! (
245
221
i8 as i64 ,
246
222
crate :: builtin:: meta:: FromFfiError :: I8 ,
247
223
sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8
248
224
) ;
249
225
impl_godot_scalar ! (
250
- u32 as i64 ,
251
- crate :: builtin:: meta:: FromFfiError :: U32 ,
252
- sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32
226
+ u8 as i64 ,
227
+ crate :: builtin:: meta:: FromFfiError :: U8 ,
228
+ sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8
229
+ ) ;
230
+ impl_godot_scalar ! (
231
+ i16 as i64 ,
232
+ crate :: builtin:: meta:: FromFfiError :: I16 ,
233
+ sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16
253
234
) ;
254
235
impl_godot_scalar ! (
255
236
u16 as i64 ,
256
237
crate :: builtin:: meta:: FromFfiError :: U16 ,
257
238
sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT16
258
239
) ;
259
240
impl_godot_scalar ! (
260
- u8 as i64 ,
261
- crate :: builtin:: meta:: FromFfiError :: U8 ,
262
- sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8
241
+ i32 as i64 ,
242
+ crate :: builtin:: meta:: FromFfiError :: I32 ,
243
+ sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32
263
244
) ;
264
245
impl_godot_scalar ! (
265
- u64 as i64 ,
266
- sys :: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64 ;
267
- lossy
246
+ u32 as i64 ,
247
+ crate :: builtin :: meta :: FromFfiError :: U32 ,
248
+ sys :: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32
268
249
) ;
269
250
impl_godot_scalar ! (
270
251
f32 as f64 ,
271
252
sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT ;
272
253
lossy
273
254
) ;
274
255
256
+ // ----------------------------------------------------------------------------------------------------------------------------------------------
257
+ // u64: manually implemented, to ensure that type is not altered during conversion.
258
+
259
+ impl GodotType for u64 {
260
+ type Ffi = i64 ;
261
+
262
+ fn to_ffi ( & self ) -> Self :: Ffi {
263
+ * self as i64
264
+ }
265
+
266
+ fn into_ffi ( self ) -> Self :: Ffi {
267
+ self as i64
268
+ }
269
+
270
+ fn try_from_ffi ( ffi : Self :: Ffi ) -> Result < Self , ConvertError > {
271
+ // Ok(ffi as u64)
272
+ Self :: try_from ( ffi)
273
+ . map_err ( |_rust_err| crate :: builtin:: meta:: FromFfiError :: U64 . into_error ( ffi) )
274
+ }
275
+
276
+ impl_godot_scalar ! ( @shared_fns; i64 , sys:: GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT64 ) ;
277
+ }
278
+
279
+ impl GodotConvert for u64 {
280
+ type Via = u64 ;
281
+ }
282
+
283
+ impl ToGodot for u64 {
284
+ fn to_godot ( & self ) -> Self :: Via {
285
+ * self
286
+ }
287
+
288
+ fn to_variant ( & self ) -> Variant {
289
+ // TODO panic doesn't fit the trait's infallibility too well; maybe in the future try_to_godot/try_to_variant() methods are possible.
290
+ i64:: try_from ( * self )
291
+ . map ( |v| v. to_variant ( ) )
292
+ . unwrap_or_else ( |_| {
293
+ panic ! ( "to_variant(): u64 value {} is not representable inside Variant, which can only store i64 integers" , self )
294
+ } )
295
+ }
296
+ }
297
+
298
+ impl FromGodot for u64 {
299
+ fn try_from_godot ( via : Self :: Via ) -> Result < Self , ConvertError > {
300
+ Ok ( via)
301
+ }
302
+
303
+ fn try_from_variant ( variant : & Variant ) -> Result < Self , ConvertError > {
304
+ // Fail for values that are not representable as u64.
305
+ let value = variant. try_to :: < i64 > ( ) ?;
306
+
307
+ u64:: try_from ( value) . map_err ( |_rust_err| {
308
+ // TODO maybe use better error enumerator
309
+ crate :: builtin:: meta:: FromVariantError :: BadValue . into_error ( value)
310
+ } )
311
+ }
312
+ }
313
+
275
314
// ----------------------------------------------------------------------------------------------------------------------------------------------
276
315
// Raw pointers
277
316
0 commit comments