use godot_ffi as sys;
use crate::builtin;
use crate::builtin::{Variant, VariantType};
use crate::meta::error::ConvertError;
use crate::meta::{FromGodot, GodotConvert, ToGodot, sealed};
use crate::registry::info::ParamMetadata;
#[rustfmt::skip] pub use sys::{ExtVariantType, GodotFfi};
pub use crate::builtin::meta_reexport::PackedElement;
#[doc(hidden)]
pub trait GodotFfiVariant: Sized + GodotFfi {
fn ffi_to_variant(&self) -> Variant;
fn ffi_from_variant(variant: &Variant) -> Result<Self, ConvertError>;
}
pub trait GodotType: GodotConvert<Via = Self> + Clone + sealed::Sealed + Sized + 'static
{
#[doc(hidden)]
type Ffi: GodotFfiVariant + 'static;
#[doc(hidden)]
type ToFfi<'f>: GodotFfiVariant
where
Self: 'f;
#[doc(hidden)]
fn to_ffi(&self) -> Self::ToFfi<'_>;
#[doc(hidden)]
fn into_ffi(self) -> Self::Ffi;
#[doc(hidden)]
fn try_from_ffi(ffi: Self::Ffi) -> Result<Self, ConvertError>;
#[doc(hidden)]
fn from_ffi(ffi: Self::Ffi) -> Self {
Self::try_from_ffi(ffi).expect("Failed conversion from FFI representation to Rust type")
}
#[doc(hidden)]
fn default_metadata() -> ParamMetadata {
ParamMetadata::NONE
}
#[doc(hidden)]
fn qualifies_as_special_none(_from_variant: &Variant) -> bool {
false
}
#[doc(hidden)]
fn as_object_arg(&self) -> crate::meta::ObjectArg<'_> {
panic!(
"as_object_arg() called for non-object type: {}",
std::any::type_name::<Self>()
)
}
}
pub(crate) trait GodotNullableType: GodotType {
#[doc(hidden)]
fn ffi_null() -> Self::Ffi;
#[doc(hidden)]
fn ffi_null_ref<'f>() -> Self::ToFfi<'f>
where
Self: 'f;
#[doc(hidden)]
fn ffi_is_null(ffi: &Self::Ffi) -> bool;
}
#[diagnostic::on_unimplemented(
message = "Element type not supported in Godot Array or Dictionary (no nesting).",
label = "has invalid element type"
)]
pub trait Element: ToGodot + FromGodot + 'static {
#[doc(hidden)]
fn debug_validate_elements(_array: &builtin::Array<Self>) -> Result<(), ConvertError> {
Ok(())
}
}
#[doc(hidden)]
pub const fn element_variant_type<T: Element>() -> VariantType {
<T::Via as GodotType>::Ffi::VARIANT_TYPE.variant_as_nil()
}
#[doc(hidden)]
pub(crate) const fn ffi_variant_type<T: GodotConvert + ?Sized>() -> ExtVariantType {
<T::Via as GodotType>::Ffi::VARIANT_TYPE
}
#[diagnostic::on_unimplemented(
message = "#[opt(default = ...)] only supports a set of truly immutable types",
label = "this type is not immutable and thus not eligible for a default value"
)]
pub unsafe trait GodotImmutable: GodotConvert + Sized {
fn into_runtime_immutable(self) -> Self {
self
}
}
mod godot_immutable_impls {
use super::GodotImmutable;
use crate::builtin::*;
use crate::meta::Element;
unsafe impl GodotImmutable for bool {}
unsafe impl GodotImmutable for i8 {}
unsafe impl GodotImmutable for u8 {}
unsafe impl GodotImmutable for i16 {}
unsafe impl GodotImmutable for u16 {}
unsafe impl GodotImmutable for i32 {}
unsafe impl GodotImmutable for u32 {}
unsafe impl GodotImmutable for i64 {}
unsafe impl GodotImmutable for f32 {}
unsafe impl GodotImmutable for f64 {}
unsafe impl GodotImmutable for Aabb {}
unsafe impl GodotImmutable for Basis {}
unsafe impl GodotImmutable for Color {}
unsafe impl GodotImmutable for GString {}
unsafe impl GodotImmutable for Plane {}
unsafe impl GodotImmutable for Projection {}
unsafe impl GodotImmutable for Quaternion {}
unsafe impl GodotImmutable for Rect2 {}
unsafe impl GodotImmutable for Rect2i {}
unsafe impl GodotImmutable for StringName {}
unsafe impl GodotImmutable for Transform2D {}
unsafe impl GodotImmutable for Transform3D {}
unsafe impl GodotImmutable for Vector2 {}
unsafe impl GodotImmutable for Vector2i {}
unsafe impl GodotImmutable for Vector3 {}
unsafe impl GodotImmutable for Vector3i {}
unsafe impl GodotImmutable for Vector4 {}
unsafe impl GodotImmutable for Vector4i {}
unsafe impl GodotImmutable for PackedByteArray {}
unsafe impl GodotImmutable for PackedColorArray {}
unsafe impl GodotImmutable for PackedFloat32Array {}
unsafe impl GodotImmutable for PackedFloat64Array {}
unsafe impl GodotImmutable for PackedInt32Array {}
unsafe impl GodotImmutable for PackedInt64Array {}
unsafe impl GodotImmutable for PackedStringArray {}
unsafe impl GodotImmutable for PackedVector2Array {}
unsafe impl GodotImmutable for PackedVector3Array {}
#[cfg(since_api = "4.3")] #[cfg_attr(published_docs, doc(cfg(since_api = "4.3")))]
unsafe impl GodotImmutable for PackedVector4Array {}
unsafe impl<T> GodotImmutable for Array<T>
where
T: GodotImmutable + Element,
{
fn into_runtime_immutable(self) -> Self {
self.into_read_only()
}
}
}