Skip to content

Commit a971839

Browse files
committed
Gd::try_cast() now returns Err(self) instead of None on failure
1 parent 8f8adb0 commit a971839

File tree

4 files changed

+17
-14
lines changed

4 files changed

+17
-14
lines changed

godot-core/src/engine/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl PackedSceneExt for PackedScene {
5959
where
6060
T: Inherits<Node>,
6161
{
62-
self.instantiate().and_then(|gd| gd.try_cast::<T>())
62+
self.instantiate().and_then(|gd| gd.try_cast::<T>().ok())
6363
}
6464
}
6565

@@ -102,7 +102,7 @@ impl NodeExt for Node {
102102

103103
// TODO differentiate errors (not found, bad type) with Result
104104
self.get_node_or_null(path)
105-
.and_then(|node| node.try_cast::<T>())
105+
.and_then(|node| node.try_cast::<T>().ok())
106106
}
107107
}
108108

@@ -252,5 +252,5 @@ where
252252
.load_ex(path.clone())
253253
.type_hint(T::class_name().to_godot_string())
254254
.done() // TODO unclone
255-
.and_then(|res| res.try_cast::<T>())
255+
.and_then(|res| res.try_cast::<T>().ok())
256256
}

godot-core/src/obj/gd.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,12 +308,12 @@ impl<T: GodotClass> Gd<T> {
308308
/// If `T`'s dynamic type is not `Derived` or one of its subclasses, `None` is returned
309309
/// and the reference is dropped. Otherwise, `Some` is returned and the ownership is moved
310310
/// to the returned value.
311-
// TODO consider Result<Gd<Derived>, Self> so that user can still use original object (e.g. to free if manual)
312-
pub fn try_cast<Derived>(self) -> Option<Gd<Derived>>
311+
pub fn try_cast<Derived>(self) -> Result<Gd<Derived>, Self>
313312
where
314313
Derived: GodotClass + Inherits<T>,
315314
{
316-
self.owned_cast().ok()
315+
// Separate method due to more restrictive bounds.
316+
self.owned_cast()
317317
}
318318

319319
/// ⚠️ **Downcast:** convert into a smart pointer to a derived class. Panics on error.

itest/rust/src/object_tests/object_test.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ fn object_reject_invalid_downcast() {
552552
let instance = Gd::from_object(CustomClassA {});
553553
let object = instance.upcast::<Object>();
554554

555-
assert!(object.try_cast::<CustomClassB>().is_none());
555+
assert!(object.try_cast::<CustomClassB>().is_err());
556556
}
557557

558558
#[itest]
@@ -577,11 +577,12 @@ fn object_engine_downcast_reflexive() {
577577
#[itest]
578578
fn object_engine_bad_downcast() {
579579
let object: Gd<Object> = Object::new_alloc();
580-
let free_ref = object.clone();
581-
let node3d: Option<Gd<Node3D>> = object.try_cast::<Node3D>();
580+
let object2 = object.clone();
582581

583-
assert!(node3d.is_none());
584-
free_ref.free();
582+
let node3d: Result<Gd<Node3D>, Gd<Object>> = object.try_cast::<Node3D>();
583+
584+
assert_eq!(node3d, Err(object2.clone()));
585+
object2.free();
585586
}
586587

587588
#[itest]
@@ -665,9 +666,11 @@ fn object_user_downcast() {
665666
fn object_user_bad_downcast() {
666667
let obj = user_refc_instance();
667668
let object = obj.upcast::<Object>();
668-
let node3d: Option<Gd<Node>> = object.try_cast::<Node>();
669+
let object2 = object.clone();
670+
671+
let node3d: Result<Gd<Node>, Gd<Object>> = object.try_cast::<Node>();
669672

670-
assert!(node3d.is_none());
673+
assert_eq!(node3d, Err(object2));
671674
}
672675

673676
#[itest]

itest/rust/src/object_tests/virtual_methods_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ fn test_format_loader(_test_context: &TestContext) {
376376
.cache_mode(CacheMode::CACHE_MODE_IGNORE)
377377
.done()
378378
.unwrap();
379-
assert!(resource.try_cast::<BoxMesh>().is_some());
379+
assert!(resource.try_cast::<BoxMesh>().is_ok());
380380

381381
loader.remove_resource_format_loader(format_loader.upcast());
382382
}

0 commit comments

Comments
 (0)