use super::Unify;
use crate::{
core::{LVar, Value},
ReadyState,
};
pub trait Reify {
type Reified;
fn reify_in(&self, state: &ReadyState) -> Option<Self::Reified>;
}
impl<T: Unify + Reify> Reify for Value<T> {
type Reified = T::Reified;
fn reify_in(&self, state: &ReadyState) -> Option<Self::Reified> {
state.resolve(self).resolved()?.reify_in(state)
}
}
impl<T: Unify + Reify> Reify for LVar<T> {
type Reified = T::Reified;
fn reify_in(&self, state: &ReadyState) -> Option<Self::Reified> {
state.resolve(&self.into()).resolved()?.reify_in(state)
}
}
macro_rules! impl_reify_copy {
($($type:ty),+) => {
$(
impl Reify for $type {
type Reified = $type;
fn reify_in(&self, _: &ReadyState) -> Option<$type> {
Some(*self)
}
}
)+
}
}
macro_rules! impl_reify_clone {
($($type:ty),+) => {
$(
impl Reify for $type {
type Reified = $type;
fn reify_in(&self, _: &ReadyState) -> Option<$type> {
Some(self.clone())
}
}
)+
}
}
impl_reify_copy!(i8, i16, i32, i64, u8, u16, u32, u64, isize, usize, f32, f64);
impl_reify_copy!(&'static str, bool, char);
impl_reify_clone!(String);
#[cfg(test)]
mod tests {
use crate::{Reify, State, Value};
#[test]
fn reify_copy() {
let resolved = Value::new(1);
assert_eq!(resolved.reify_in(&State::new().ready().unwrap()), Some(1));
}
#[test]
fn reify_clone() {
let resolved = Value::new("foo".to_string());
assert_eq!(
resolved.reify_in(&State::new().ready().unwrap()),
Some("foo".to_string())
);
}
}