Skip to content

Commit 9016ae2

Browse files
authored
Merge pull request #467 from lilizoey/feature/godot-convert-result2
Make `FromGodot` conversions fallible
2 parents 13ab375 + 20b0f50 commit 9016ae2

File tree

25 files changed

+848
-284
lines changed

25 files changed

+848
-284
lines changed

godot-codegen/src/class_generator.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -925,8 +925,8 @@ fn make_native_structure(
925925
}
926926

927927
impl FromGodot for *mut #class_name {
928-
fn try_from_godot(via: Self::Via) -> Option<Self> {
929-
Some(via as Self)
928+
fn try_from_godot(via: Self::Via) -> Result<Self, crate::builtin::meta::ConvertError> {
929+
Ok(via as Self)
930930
}
931931
}
932932

@@ -941,8 +941,8 @@ fn make_native_structure(
941941
}
942942

943943
impl FromGodot for *const #class_name {
944-
fn try_from_godot(via: Self::Via) -> Option<Self> {
945-
Some(via as Self)
944+
fn try_from_godot(via: Self::Via) -> Result<Self, crate::builtin::meta::ConvertError> {
945+
Ok(via as Self)
946946
}
947947
}
948948
};
@@ -1286,6 +1286,7 @@ fn make_builtin_method_definition(
12861286

12871287
<CallSig as PtrcallSignatureTuple>::out_builtin_ptrcall::<RetMarshal>(
12881288
method_bind,
1289+
#method_name_str,
12891290
#object_ptr,
12901291
args
12911292
)
@@ -1345,6 +1346,7 @@ pub(crate) fn make_utility_function_definition(
13451346

13461347
<CallSig as PtrcallSignatureTuple>::out_utility_ptrcall(
13471348
utility_fn,
1349+
#function_name_str,
13481350
args
13491351
)
13501352
};
@@ -1354,6 +1356,7 @@ pub(crate) fn make_utility_function_definition(
13541356

13551357
<CallSig as VarcallSignatureTuple>::out_utility_ptrcall_varargs(
13561358
utility_fn,
1359+
#function_name_str,
13571360
args,
13581361
varargs
13591362
)

godot-codegen/src/util.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,9 @@ pub fn make_enum_definition(enum_: &Enum) -> TokenStream {
337337
}
338338

339339
impl crate::builtin::meta::FromGodot for #enum_name {
340-
fn try_from_godot(via: Self::Via) -> Option<Self> {
340+
fn try_from_godot(via: Self::Via) -> std::result::Result<Self, crate::builtin::meta::ConvertError> {
341341
<Self as crate::obj::EngineEnum>::try_from_ord(via)
342+
.ok_or_else(|| crate::builtin::meta::FromGodotError::InvalidEnum.into_error(via))
342343
}
343344
}
344345

godot-core/src/builtin/array.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use std::fmt;
1313
use std::marker::PhantomData;
1414
use sys::{ffi_methods, interface_fn, GodotFfi};
1515

16-
use super::meta::{FromGodot, GodotConvert, GodotFfiVariant, GodotType, ToGodot};
16+
use super::meta::{
17+
ConvertError, FromGodot, FromGodotError, FromVariantError, GodotConvert, GodotFfiVariant,
18+
GodotType, ToGodot,
19+
};
1720

1821
/// Godot's `Array` type.
1922
///
@@ -337,11 +340,18 @@ impl<T: GodotType> Array<T> {
337340
}
338341

339342
/// Checks that the inner array has the correct type set on it for storing elements of type `T`.
340-
fn with_checked_type(self) -> Result<Self, VariantConversionError> {
341-
if self.type_info() == TypeInfo::of::<T>() {
343+
fn with_checked_type(self) -> Result<Self, ConvertError> {
344+
let self_ty = self.type_info();
345+
let target_ty = TypeInfo::of::<T>();
346+
347+
if self_ty == target_ty {
342348
Ok(self)
343349
} else {
344-
Err(VariantConversionError::BadType)
350+
Err(FromGodotError::BadArrayType {
351+
expected: target_ty,
352+
got: self_ty,
353+
}
354+
.into_error(self))
345355
}
346356
}
347357

@@ -633,11 +643,15 @@ impl<T: GodotType> ToGodot for Array<T> {
633643
fn into_godot(self) -> Self::Via {
634644
self
635645
}
646+
647+
fn to_variant(&self) -> Variant {
648+
self.ffi_to_variant()
649+
}
636650
}
637651

638652
impl<T: GodotType> FromGodot for Array<T> {
639-
fn try_from_godot(via: Self::Via) -> Option<Self> {
640-
Some(via)
653+
fn try_from_godot(via: Self::Via) -> Result<Self, ConvertError> {
654+
Ok(via)
641655
}
642656
}
643657

@@ -755,15 +769,16 @@ impl<T: GodotType> GodotType for Array<T> {
755769
type Ffi = Self;
756770

757771
fn to_ffi(&self) -> Self::Ffi {
772+
// `to_ffi` is sometimes intentionally called with an array in an invalid state.
758773
self.clone()
759774
}
760775

761776
fn into_ffi(self) -> Self::Ffi {
762777
self
763778
}
764779

765-
fn try_from_ffi(ffi: Self::Ffi) -> Option<Self> {
766-
Some(ffi)
780+
fn try_from_ffi(ffi: Self::Ffi) -> Result<Self, ConvertError> {
781+
Ok(ffi)
767782
}
768783

769784
fn godot_type_name() -> String {
@@ -781,9 +796,13 @@ impl<T: GodotType> GodotFfiVariant for Array<T> {
781796
}
782797
}
783798

784-
fn ffi_from_variant(variant: &Variant) -> Result<Self, VariantConversionError> {
799+
fn ffi_from_variant(variant: &Variant) -> Result<Self, ConvertError> {
785800
if variant.get_type() != Self::variant_type() {
786-
return Err(VariantConversionError::BadType);
801+
return Err(FromVariantError::BadType {
802+
expected: Self::variant_type(),
803+
got: variant.get_type(),
804+
}
805+
.into_error(variant.clone()));
787806
}
788807

789808
let array = unsafe {
@@ -992,7 +1011,7 @@ macro_rules! varray {
9921011
///
9931012
/// We ignore the `script` parameter because it has no impact on typing in Godot.
9941013
#[derive(PartialEq, Eq)]
995-
struct TypeInfo {
1014+
pub(crate) struct TypeInfo {
9961015
variant_type: VariantType,
9971016

9981017
/// Not a `ClassName` because some values come from Godot engine API.
@@ -1007,9 +1026,17 @@ impl TypeInfo {
10071026
}
10081027
}
10091028

1010-
fn is_typed(&self) -> bool {
1029+
pub fn is_typed(&self) -> bool {
10111030
self.variant_type != VariantType::Nil
10121031
}
1032+
1033+
pub fn variant_type(&self) -> VariantType {
1034+
self.variant_type
1035+
}
1036+
1037+
pub fn class_name(&self) -> &StringName {
1038+
&self.class_name
1039+
}
10131040
}
10141041

10151042
impl fmt::Debug for TypeInfo {

0 commit comments

Comments
 (0)