trellis-core 0.1.2

Deterministic reactive resource graph core types.
Documentation
use core::any::{Any, TypeId};

pub(crate) trait StoredInput: Any + Send + Sync {
    fn clone_box(&self) -> Box<dyn StoredInput>;
    fn equals(&self, other: &dyn StoredInput) -> bool;
    fn as_any(&self) -> &dyn Any;
}

impl Clone for Box<dyn StoredInput> {
    fn clone(&self) -> Self {
        self.clone_box()
    }
}

#[derive(Clone)]
pub(crate) struct InputValue<T> {
    value: T,
}

impl<T> InputValue<T> {
    pub(crate) fn new(value: T) -> Self {
        Self { value }
    }

    pub(crate) fn get(&self) -> &T {
        &self.value
    }
}

impl<T> StoredInput for InputValue<T>
where
    T: Clone + PartialEq + Send + Sync + 'static,
{
    fn clone_box(&self) -> Box<dyn StoredInput> {
        Box::new(self.clone())
    }

    fn equals(&self, other: &dyn StoredInput) -> bool {
        other
            .as_any()
            .downcast_ref::<InputValue<T>>()
            .is_some_and(|other| self.value == other.value)
    }

    fn as_any(&self) -> &dyn Any {
        self
    }
}

pub(crate) fn boxed_input<T>(value: T) -> Box<dyn StoredInput>
where
    T: Clone + PartialEq + Send + Sync + 'static,
{
    Box::new(InputValue::new(value))
}

pub(crate) fn downcast_input<T>(value: &dyn StoredInput) -> Option<&T>
where
    T: Clone + PartialEq + Send + Sync + 'static,
{
    value
        .as_any()
        .downcast_ref::<InputValue<T>>()
        .map(InputValue::get)
}

pub(crate) fn value_type<T>() -> TypeId
where
    T: 'static,
{
    TypeId::of::<T>()
}