pr47 0.0.3

A semi-experimental programming language. Still working in progress.
Documentation
use crate::vm::{Pr47Ptr, Pr47Wrapper, Pr47DynBase};
use crate::error::Pr47Error;

pub trait CastIntoPr47<'a, T: 'a> {
    fn cast_from_any(t: T) -> Result<Pr47Ptr<'a>, Pr47Error>;
}

impl<'a, T: 'a> CastIntoPr47<'a, T> for Pr47Ptr<'a> {
    default fn cast_from_any(t: T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        <Pr47Ptr<'a> as PutIntoPtr<'a, T>>::put_into_ptr(t)
    }
}

impl<'a, T: 'a> CastIntoPr47<'a, Option<T>> for Pr47Ptr<'a> {
    fn cast_from_any(t: Option<T>) -> Result<Pr47Ptr<'a>, Pr47Error> {
        match t {
            Some(value) => <Pr47Ptr<'a> as PutIntoPtr<'a, T>>::put_into_ptr(value),
            None => Ok(Pr47Ptr::nullptr()),
        }
    }
}

impl<'a, T: 'a, E: 'static + std::error::Error> CastIntoPr47<'a, Result<T, E>> for Pr47Ptr<'a> {
    fn cast_from_any(result: Result<T, E>) -> Result<Pr47Ptr<'a>, Pr47Error> {
        match result {
            Ok(value) => <Pr47Ptr as CastIntoPr47<T>>::cast_from_any(value),
            Err(e) => Err(Pr47Error::RustException { rust_error: Box::new(e) })
        }
    }
}

trait PutIntoPtr<'a, T: 'a> {
    fn put_into_ptr(value: T) -> Result<Pr47Ptr<'a>, Pr47Error>;
}

impl<'a, T: 'a> PutIntoPtr<'a, T> for Pr47Ptr<'a> {
    default fn put_into_ptr(value: T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        <Pr47Ptr<'a> as PutIntoPtrValue<'a, T>>::put_into_ptr_value(value)
    }
}

impl<'a, T: 'a + Pr47DynBase> PutIntoPtr<'a, &'a T> for Pr47Ptr<'a> {
    fn put_into_ptr(value: &'a T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        Ok(Pr47Ptr::shared(value))
    }
}

impl<'a, T: 'a + Pr47DynBase> PutIntoPtr<'a, &'a mut T> for Pr47Ptr<'a> {
    fn put_into_ptr(value: &'a mut T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        Ok(Pr47Ptr::shared_mut(value))
    }
}

trait PutIntoPtrValue<'a, T: 'a> {
    fn put_into_ptr_value(value: T) -> Result<Pr47Ptr<'a>, Pr47Error>;
}

impl<'a, T: 'a> PutIntoPtrValue<'a, T> for Pr47Ptr<'a> {
    default fn put_into_ptr_value(value: T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        Ok(Pr47Ptr::owned(Pr47Wrapper::new(value)))
    }
}

impl<'a, T: 'a + Pr47DynBase> PutIntoPtrValue<'a, T> for Pr47Ptr<'a> {
    fn put_into_ptr_value(value: T) -> Result<Pr47Ptr<'a>, Pr47Error> {
        Ok(Pr47Ptr::owned(value))
    }
}

#[cfg(test)]
mod test {
    use crate::vm::Pr47Ptr;
    use crate::bind::casts::CastIntoPr47;

    #[test]
    fn test_put_success() {
        let x: i32 = 5;
        let p = <Pr47Ptr as CastIntoPr47<&i32>>::cast_from_any(&x).unwrap();
    }
}