use std::{any::{self, Any}, marker::Unsize};
use crate::upcast::Upcast;
use self::{downcast::{DowncastRef, DowncastFromRef}, upcast::TryUpcastRef};
use super::*;
pub trait Convert<Obj>: Is<Obj>
where
Obj: ?Sized
{
fn convert_from(object: Box<Obj>) -> Box<Self>;
fn convert(object: &mut Box<Obj>);
fn convert_get(object: &mut Box<Obj>) -> &Self;
fn convert_get_mut(object: &mut Box<Obj>) -> &mut Self;
}
impl<To, Obj> Convert<Obj> for To
where
To: Is<Obj> + Unsize<Obj> + 'static,
Obj: ConvertInto<Self> + AsAny + ?Sized + 'static,
Box<Obj>: Clone
{
fn convert_from(object: Box<Obj>) -> Box<Self>
{
object.convert_into()
}
fn convert(object: &mut Box<Obj>)
{
if Self::downcast_from_ref(&**object).is_none()
{
*object = object.clone().convert_into()
}
}
fn convert_get(object: &mut Box<Obj>) -> &Self
{
Self::convert(object);
(&**object).downcast_ref().unwrap()
}
fn convert_get_mut(object: &mut Box<Obj>) -> &mut Self
{
Self::convert(object);
(&mut **object).downcast_mut().unwrap()
}
}