use super::*;
use crate::__private::Sealed;
pub unsafe trait AsObject<'a>: Sealed + Sized + Debug + Display + Copy + Into<Object<'a>> + Into<FREObject> {
const TYPE: Type;
#[inline]
fn as_object (self) -> Object<'a> {unsafe {transmute_unchecked(self)}}
#[allow(unsafe_op_in_unsafe_fn)]
#[inline]
unsafe fn as_unchecked <T: AsObject<'a>> (self) -> T {T::from_unchecked(self)}
#[inline]
unsafe fn from_unchecked <O: AsObject<'a>> (object: O) -> Self {
#[cfg(debug_assertions)]
if object.is_null() && Self::TYPE != Object::TYPE && Self::TYPE != Type::null {
panic!("Cannot cast `null` to `{}`.", Self::TYPE);
}
unsafe {transmute_unchecked(object)}
}
#[inline]
fn as_ptr (self) -> FREObject {unsafe {transmute_unchecked(self)}}
#[inline]
fn is_null(self) -> bool {false}
fn get_type(self) -> Type {
let mut ty = MaybeUninit::<FREObjectType>::uninit();
let r = unsafe {FREGetObjectType(self.as_ptr(), ty.as_mut_ptr())};
if r.is_ok() {
let ty = unsafe {ty.assume_init()};
ty.into()
} else if r == FREResult::FRE_WRONG_THREAD {
Type::null
} else {unreachable!()}
}
fn get_property (self, name: UCStr) -> Result<Object<'a>, ExternalError<'a>> {
let mut object = MaybeUninit::<FREObject>::uninit();
let mut thrown = MaybeUninit::<FREObject>::uninit();
let r = unsafe {FREGetObjectProperty(self.as_ptr(), name.as_ptr(), object.as_mut_ptr(), thrown.as_mut_ptr())};
if let Some(e) = ExternalError::try_from(r, Some(unsafe {transmute(thrown)})) {
Err(e)
}else{
Ok(unsafe {transmute(object)})
}
}
fn set_property <O: AsObject<'a>> (self, name: UCStr, value: O) -> Result<(), ExternalError<'a>> {
let mut thrown = MaybeUninit::<FREObject>::uninit();
let r = unsafe {FRESetObjectProperty(self.as_ptr(), name.as_ptr(), value.as_ptr(), thrown.as_mut_ptr())};
if let Some(e) = ExternalError::try_from(r, Some(unsafe {transmute(thrown)})) {
Err(e)
}else{
Ok(())
}
}
fn call_method (self, name: UCStr, args: Option<&[Object]>) -> Result<Object<'a>, ExternalError<'a>> {
let args = args.unwrap_or_default();
debug_assert!(args.len() <= u32::MAX as usize);
let mut object = MaybeUninit::<FREObject>::uninit();
let mut thrown = MaybeUninit::<FREObject>::uninit();
let r = unsafe {FRECallObjectMethod(self.as_ptr(), name.as_ptr(), args.len() as u32, transmute(args.as_ptr()), object.as_mut_ptr(), thrown.as_mut_ptr())};
if let Some(e) = ExternalError::try_from(r, Some(unsafe {transmute(thrown)})) {
Err(e)
}else{
Ok(unsafe {transmute(object)})
}
}
#[allow(non_snake_case)]
fn toString (self) -> Result<as3::String<'a>, ExternalError<'a>> {
self.call_method(crate::ucstringify!(toString), None).map(|r|r.try_as().unwrap())
}
}
impl<'a, O> From<O> for Object<'a>
where O: AsNonNullObject<'a> {
fn from(object: O) -> Self {object.as_object()}
}
pub trait AsNonNullObject<'a>: AsObject<'a> {
#[inline]
fn as_non_null_object(self) -> NonNullObject<'a> {unsafe {self.as_unchecked()}}
}
pub trait TryAs<'a, T>: AsObject<'a> + TryInto<T, Error = Type>
where T: AsObject<'a> + TryFrom<Self, Error = Type> {
fn try_as (self) -> Result<T, Type>;
}
impl<'a, O, T> TryAs<'a, T> for O
where
O: AsObject<'a> + TryInto<T, Error = Type>,
T: AsObject<'a> + TryFrom<O, Error = Type>,
{
fn try_as (self) -> Result<T, Type> {T::try_from(self)}
}
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct Object<'a> (FREObject, PhantomData<&'a ()>);
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct NonNullObject<'a> (NonNull<c_void>, PhantomData<&'a ()>);
impl<'a> Object<'a> {
pub fn new (ctx: &CurrentContext<'a>) -> NonNullObject<'a> {NonNullObject::new(ctx)}
pub fn non_null (self) -> Option<NonNullObject<'a>> {NonNullObject::from_object(self)}
}
impl<'a> NonNullObject<'a> {
pub fn new (ctx: &CurrentContext<'a>) -> Self {ctx.construct(crate::ucstringify!(Object), None).unwrap()}
pub fn from_object (object: Object<'a>) -> Option<NonNullObject<'a>> {NonNull::new(object.0).map(|object|unsafe {transmute(object)})}
}
impl<'a> TryFrom<Object<'a>> for NonNullObject<'a> {
type Error = ();
fn try_from(object: Object<'a>) -> Result<Self, Self::Error> {Self::from_object(object).ok_or(())}
}
impl TryFrom<Object<'_>> for i32 {
type Error = FfiError;
fn try_from(object: Object) -> Result<Self, Self::Error> {
let mut value = MaybeUninit::<i32>::uninit();
let r = unsafe {FREGetObjectAsInt32(object.0, value.as_mut_ptr())};
if let Ok(e) = r.try_into() {return Err(e);}
let value = unsafe {value.assume_init()};
Ok(value)
}
}
impl TryFrom<&Object<'_>> for i32 {type Error = FfiError; fn try_from(object: &Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut Object<'_>> for i32 {type Error = FfiError; fn try_from(object: &mut Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<NonNullObject<'_>> for i32 {type Error = FfiError; fn try_from(object: NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&NonNullObject<'_>> for i32 {type Error = FfiError; fn try_from(object: &NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut NonNullObject<'_>> for i32 {type Error = FfiError; fn try_from(object: &mut NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<Object<'_>> for u32 {
type Error = FfiError;
fn try_from(object: Object) -> Result<Self, Self::Error> {
let mut value = MaybeUninit::<u32>::uninit();
let r = unsafe {FREGetObjectAsUint32(object.0, value.as_mut_ptr())};
if let Ok(e) = r.try_into() {return Err(e);}
let value = unsafe {value.assume_init()};
Ok(value)
}
}
impl TryFrom<&Object<'_>> for u32 {type Error = FfiError; fn try_from(object: &Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut Object<'_>> for u32 {type Error = FfiError; fn try_from(object: &mut Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<NonNullObject<'_>> for u32 {type Error = FfiError; fn try_from(object: NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&NonNullObject<'_>> for u32 {type Error = FfiError; fn try_from(object: &NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut NonNullObject<'_>> for u32 {type Error = FfiError; fn try_from(object: &mut NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<Object<'_>> for f64 {
type Error = FfiError;
fn try_from(object: Object) -> Result<Self, Self::Error> {
let mut value = MaybeUninit::<f64>::uninit();
let r = unsafe {FREGetObjectAsDouble(object.0, value.as_mut_ptr())};
if let Ok(e) = r.try_into() {return Err(e);}
let value = unsafe {value.assume_init()};
Ok(value)
}
}
impl TryFrom<&Object<'_>> for f64 {type Error = FfiError; fn try_from(object: &Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut Object<'_>> for f64 {type Error = FfiError; fn try_from(object: &mut Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<NonNullObject<'_>> for f64 {type Error = FfiError; fn try_from(object: NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&NonNullObject<'_>> for f64 {type Error = FfiError; fn try_from(object: &NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut NonNullObject<'_>> for f64 {type Error = FfiError; fn try_from(object: &mut NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<Object<'_>> for bool {
type Error = FfiError;
fn try_from(object: Object) -> Result<Self, Self::Error> {
let mut value = MaybeUninit::<u32>::uninit();
let r = unsafe {FREGetObjectAsBool(object.0, value.as_mut_ptr())};
if let Ok(e) = r.try_into() {return Err(e);}
let value = unsafe {value.assume_init()};
Ok(value != 0)
}
}
impl TryFrom<&Object<'_>> for bool {type Error = FfiError; fn try_from(object: &Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut Object<'_>> for bool {type Error = FfiError; fn try_from(object: &mut Object) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<NonNullObject<'_>> for bool {type Error = FfiError; fn try_from(object: NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&NonNullObject<'_>> for bool {type Error = FfiError; fn try_from(object: &NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl TryFrom<&mut NonNullObject<'_>> for bool {type Error = FfiError; fn try_from(object: &mut NonNullObject) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl<'a> TryFrom<Object<'a>> for &'a str {
type Error = FfiError;
fn try_from(object: Object<'a>) -> Result<Self, Self::Error> {
let mut len = MaybeUninit::<u32>::uninit();
let mut ptr = MaybeUninit::<FREStr>::uninit();
let r = unsafe {FREGetObjectAsUTF8(object.0, len.as_mut_ptr(), ptr.as_mut_ptr())};
if let Ok(e) = r.try_into() {return Err(e);}
let len = unsafe {len.assume_init()};
let ptr = unsafe {ptr.assume_init()};
let bytes = unsafe {std::slice::from_raw_parts(ptr, len as usize)};
let s = unsafe {str::from_utf8_unchecked(bytes)};
Ok(s)
}
}
impl<'a> TryFrom<&Object<'a>> for &'a str {type Error = FfiError; fn try_from(object: &Object<'a>) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl<'a> TryFrom<&mut Object<'a>> for &'a str {type Error = FfiError; fn try_from(object: &mut Object<'a>) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl<'a> TryFrom<NonNullObject<'a>> for &'a str {type Error = FfiError; fn try_from(object: NonNullObject<'a>) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl<'a> TryFrom<&NonNullObject<'a>> for &'a str {type Error = FfiError; fn try_from(object: &NonNullObject<'a>) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl<'a> TryFrom<&mut NonNullObject<'a>> for &'a str {type Error = FfiError; fn try_from(object: &mut NonNullObject<'a>) -> Result<Self, Self::Error> {Self::try_from(object.as_object())}}
impl Display for Object<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(obj) = NonNullObject::from_object(*self) {
Display::fmt(&obj, f)
} else {write!(f, "null")}
}
}
impl Display for NonNullObject<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.toString() {
Ok(s) => Display::fmt(s.value(), f),
Err(ref e) => Display::fmt(e, f),
}
}
}
impl Default for Object<'_> {
fn default() -> Self {as3::null}
}
unsafe impl Sealed for Object<'_> {}
unsafe impl Sealed for NonNullObject<'_> {}
unsafe impl<'a> AsObject<'a> for Object<'a> {const TYPE: Type = Type::Named("Object");
#[inline]
fn is_null(self) -> bool {self.0.is_null() || self.get_type() == Type::null}
}
unsafe impl<'a> AsObject<'a> for NonNullObject<'a> {const TYPE: Type = Type::NonNullObject;}
impl<'a> AsNonNullObject<'a> for NonNullObject<'a> {fn as_non_null_object(self) -> NonNullObject<'a> {self}}
impl From<()> for Object<'_> {fn from(_: ()) -> Self {Self::default()}}
impl<'a, O: AsObject<'a>> From<Option<O>> for Object<'a> {
fn from(value: Option<O>) -> Self {
if let Some(obj) = value {
obj.as_object()
} else {as3::null}
}
}
impl From<Object<'_>> for FREObject {fn from(object: Object) -> Self {object.as_ptr()}}
impl From<NonNullObject<'_>> for FREObject {fn from(object: NonNullObject) -> Self {object.as_ptr()}}