spellcast 0.1.2

Casting of dynamic objects
Documentation
use std::marker::Unsize;

use crate::downcast::{DowncastRef, DowncastFromRef};

use super::*;

pub trait TryConvert<Obj>: Is<Obj>
where
    Obj: ?Sized
{
    fn try_convert_from(object: Box<Obj>) -> Result<Box<Self>, Box<Obj>>;
    fn try_convert(object: &mut Box<Obj>) -> bool;
    fn try_convert_get(object: &mut Box<Obj>) -> Option<&Self>;
    fn try_convert_get_mut(object: &mut Box<Obj>) -> Option<&mut Self>;
}
impl<'a, To, Obj> TryConvert<Obj> for To
where
    To: Is<Obj> + Unsize<Obj> + ?Sized + DowncastFromRef<Obj>,
    Obj: Is<Obj> + TryConvertInto<To, Obj> + DowncastRef<To> + ?Sized,
    Box<Obj>: Clone
{
    fn try_convert_from(object: Box<Obj>) -> Result<Box<Self>, Box<Obj>>
    {
        object.try_convert_into()
    }
    fn try_convert(object: &mut Box<Obj>) -> bool
    {
        if Self::downcast_from_ref(&**object).is_none()
        {
            match object.clone().try_convert_into()
            {
                Ok(obj) => {
                    *object = obj;
                },
                Err(obj) => {
                    *object = obj;
                    return false;
                },
            }
        }
        true
    }
    fn try_convert_get(object: &mut Box<Obj>) -> Option<&Self>
    {
        if !Self::try_convert(object)
        {
            return None
        }
        (&**object).downcast_ref()
    }
    fn try_convert_get_mut(object: &mut Box<Obj>) -> Option<&mut Self>
    {
        if !Self::try_convert(object)
        {
            return None
        }
        (&mut **object).downcast_mut()
    }
}