/*! This module enable runtime type information for the builtin items and property so that the viewer can handle them */ pub use const_field_offset::FieldOffset; use std::convert::{TryFrom, TryInto}; macro_rules! declare_ValueType { ($($ty:ty),*) => { pub trait ValueType: 'static $(+ TryInto<$ty> + TryFrom<$ty>)* {} }; } declare_ValueType![bool, u32, u64, i32, i64, f32, f64, crate::SharedString, crate::Resource]; pub trait PropertyInfo { fn get(&self, item: &Item, context: &crate::EvaluationContext) -> Result; fn set(&self, item: &Item, value: Value) -> Result<(), ()>; fn set_binding(&self, item: &Item, binding: Box Value>); /// The offset of the property in the item. /// The use of this is unsafe fn offset(&self) -> usize; } impl PropertyInfo for FieldOffset> where Value: TryInto, T: TryInto, { fn get(&self, item: &Item, context: &crate::EvaluationContext) -> Result { self.apply(item).get(context).try_into().map_err(|_| ()) } fn set(&self, item: &Item, value: Value) -> Result<(), ()> { self.apply(item).set(value.try_into().map_err(|_| ())?); Ok(()) } fn set_binding(&self, item: &Item, binding: Box Value>) { self.apply(item).set_binding(move |context| { binding(context).try_into().map_err(|_| ()).expect("binding was of the wrong type") }); } fn offset(&self) -> usize { self.get_byte_offset() } } pub trait BuiltinItem: Sized { fn name() -> &'static str; fn properties() -> Vec<(&'static str, &'static dyn PropertyInfo)>; fn signals() -> Vec<(&'static str, FieldOffset>)>; }