use super::*;
#[cfg(test)]
mod tests;
#[derive(Clone)]
pub struct Variable {
untyped_property: UntypedProperty,
converted_to_pax_value: Property<PaxValue>,
rust_type: std::any::TypeId,
}
impl Variable {
pub fn new<T: PropertyValue + ToPaxValue>(untyped_property: UntypedProperty) -> Self {
Self::new_from_typed_property(Property::<T>::new_from_untyped(untyped_property.clone()))
}
pub fn new_from_typed_property<T: PropertyValue + ToPaxValue>(property: Property<T>) -> Self {
let untyped_property = property.untyped();
let deps = [untyped_property.clone()];
let pax_value_prop = Property::computed(move || property.get().to_pax_value(), &deps);
Variable {
untyped_property,
converted_to_pax_value: pax_value_prop,
rust_type: std::any::TypeId::of::<T>(),
}
}
pub fn try_typed_binding<T: PropertyValue + CoercionRules>(
&self,
name: &str,
) -> Option<Property<T>> {
if self.rust_type != std::any::TypeId::of::<T>()
|| !self.untyped_property.has_value_type::<T>()
|| !pax_value::is_typed_binding_safe::<T>()
{
return None;
}
let source = Property::<T>::new_from_untyped(self.untyped_property.clone());
Some(Property::computed_with_name(
move || source.get(),
&[self.untyped_property.clone()],
name,
))
}
pub fn get_untyped_property(&self) -> &UntypedProperty {
&self.untyped_property
}
pub fn get_as_pax_value(&self) -> PaxValue {
self.converted_to_pax_value.get()
}
pub fn read_pax_value_ref<V>(&self, f: impl FnOnce(&PaxValue) -> V) -> V {
self.converted_to_pax_value.read(f)
}
}