@@ -71,8 +71,14 @@ use std::fmt;
71
71
/// assert_eq!(inner.class_name(), Some("MyClass"));
72
72
/// assert_eq!(inner.method_name(), "my_method");
73
73
/// }
74
- #[ derive( Debug ) ]
75
74
pub struct CallError {
75
+ // Boxed since the original struct is >= 176 bytes, making Result<..., CallError> very large.
76
+ b : Box < InnerCallError > ,
77
+ }
78
+
79
+ /// Inner struct. All functionality on outer `impl`.
80
+ #[ derive( Debug ) ]
81
+ struct InnerCallError {
76
82
class_name : String ,
77
83
function_name : String ,
78
84
call_expr : String ,
@@ -92,16 +98,16 @@ impl CallError {
92
98
/// This is the static and not the dynamic type. For example, if you invoke `call()` on a `Gd<Node>`, you are effectively invoking
93
99
/// `Object::call()` (through `DerefMut`), and the class name will be `Object`.
94
100
pub fn class_name ( & self ) -> Option < & str > {
95
- if self . class_name . is_empty ( ) {
101
+ if self . b . class_name . is_empty ( ) {
96
102
None
97
103
} else {
98
- Some ( & self . class_name )
104
+ Some ( & self . b . class_name )
99
105
}
100
106
}
101
107
102
108
/// Name of the function or method that failed.
103
109
pub fn method_name ( & self ) -> & str {
104
- & self . function_name
110
+ & self . b . function_name
105
111
}
106
112
107
113
// ------------------------------------------------------------------------------------------------------------------------------------------
@@ -150,8 +156,7 @@ impl CallError {
150
156
// If the call error encodes an error generated by us, decode it.
151
157
let mut source_error = None ;
152
158
if err. error == sys:: GODOT_RUST_CUSTOM_CALL_ERROR {
153
- source_error = crate :: private:: call_error_remove ( & err) //.
154
- . map ( |e| SourceError :: Call ( Box :: new ( e) ) ) ;
159
+ source_error = crate :: private:: call_error_remove ( & err) . map ( SourceError :: Call ) ;
155
160
}
156
161
157
162
Err ( Self :: failed_varcall_inner (
@@ -295,8 +300,8 @@ impl CallError {
295
300
// source,
296
301
// }
297
302
298
- call_error. source = source;
299
- call_error. call_expr = call_expr;
303
+ call_error. b . source = source;
304
+ call_error. b . call_expr = call_expr;
300
305
call_error
301
306
}
302
307
@@ -316,7 +321,7 @@ impl CallError {
316
321
reason : impl Into < String > ,
317
322
source : Option < ConvertError > ,
318
323
) -> Self {
319
- Self {
324
+ let inner = InnerCallError {
320
325
class_name : call_ctx. class_name . to_string ( ) ,
321
326
function_name : call_ctx. function_name . to_string ( ) ,
322
327
call_expr : format ! ( "{call_ctx}()" ) ,
@@ -325,17 +330,22 @@ impl CallError {
325
330
value : e. value ( ) . map_or_else ( String :: new, |v| format ! ( "{:?}" , v) ) ,
326
331
erased_error : e. into ( ) ,
327
332
} ) ,
328
- }
333
+ } ;
334
+
335
+ Self { b : Box :: new ( inner) }
329
336
}
330
337
331
338
/// Describes the error.
332
339
///
333
340
/// This is the same as the `Display`/`ToString` repr, but without the prefix mentioning that this is a function call error,
334
341
/// and without any source error information.
335
- fn message ( & self , with_source : bool ) -> String {
336
- let Self {
337
- call_expr, reason, ..
338
- } = self ;
342
+ pub fn message ( & self , with_source : bool ) -> String {
343
+ let InnerCallError {
344
+ call_expr,
345
+ reason,
346
+ source,
347
+ ..
348
+ } = & * self . b ;
339
349
340
350
let reason_str = if reason. is_empty ( ) {
341
351
String :: new ( )
@@ -351,7 +361,7 @@ impl CallError {
351
361
// String::new()
352
362
// };
353
363
354
- let source_str = match & self . source {
364
+ let source_str = match source {
355
365
Some ( SourceError :: Convert {
356
366
erased_error,
357
367
value,
@@ -361,7 +371,10 @@ impl CallError {
361
371
if value. is_empty( ) { "" } else { ": " } ,
362
372
)
363
373
}
364
- Some ( SourceError :: Call ( e) ) if with_source => format ! ( "\n Source: {}" , e. message( true ) ) ,
374
+ Some ( SourceError :: Call ( e) ) if with_source => {
375
+ let message = e. message ( true ) ;
376
+ format ! ( "\n Source: {message}" )
377
+ }
365
378
_ => String :: new ( ) ,
366
379
} ;
367
380
@@ -371,13 +384,21 @@ impl CallError {
371
384
372
385
impl fmt:: Display for CallError {
373
386
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
374
- write ! ( f, "godot-rust function call failed: {}" , self . message( true ) )
387
+ let message = self . message ( true ) ;
388
+ write ! ( f, "godot-rust function call failed: {message}" )
389
+ }
390
+ }
391
+
392
+ impl fmt:: Debug for CallError {
393
+ // Delegate to inner box.
394
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
395
+ write ! ( f, "{:?}" , self . b)
375
396
}
376
397
}
377
398
378
399
impl Error for CallError {
379
400
fn source ( & self ) -> Option < & ( dyn Error + ' static ) > {
380
- match self . source . as_ref ( ) {
401
+ match self . b . source . as_ref ( ) {
381
402
Some ( SourceError :: Convert {
382
403
erased_error : e, ..
383
404
} ) => deref_to :: < ErasedConvertError > ( e) ,
@@ -396,7 +417,9 @@ enum SourceError {
396
417
erased_error : ErasedConvertError ,
397
418
value : String ,
398
419
} ,
399
- Call ( Box < CallError > ) ,
420
+
421
+ // If the top-level Box on CallError is ever removed, this would need to store Box<CallError> again.
422
+ Call ( CallError ) ,
400
423
}
401
424
402
425
/// Explicit dereferencing to a certain type. Avoids accidentally returning `&Box<T>` or so.
0 commit comments