use std::time::Duration;
use crate::attributes::Attributes;
pub trait AttributeResolvable {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool;
fn resolve(&mut self, prefix: &str, attrs: &Attributes);
}
impl AttributeResolvable for f32 {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
(*self - attrs.value(prefix)).abs() > f32::EPSILON
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
*self = attrs.value(prefix);
}
}
impl AttributeResolvable for f64 {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
(*self - attrs.value(prefix) as f64).abs() > f64::EPSILON
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
*self = attrs.value(prefix) as f64;
}
}
macro_rules! impl_resolvable_int {
($($ty:ty),*) => {$(
impl AttributeResolvable for $ty {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
*self != attrs.value(prefix).round() as $ty
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
*self = attrs.value(prefix).round() as $ty;
}
}
)*};
}
impl_resolvable_int!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
impl AttributeResolvable for bool {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
*self != (attrs.value(prefix) != 0.0)
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
*self = attrs.value(prefix) != 0.0;
}
}
impl AttributeResolvable for Duration {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
let secs = attrs.value(prefix);
secs > 0.0 && (self.as_secs_f32() - secs).abs() > f32::EPSILON
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
let secs = attrs.value(prefix);
if secs > 0.0 {
*self = Duration::from_secs_f32(secs);
}
}
}
impl<T: AttributeResolvable> AttributeResolvable for Option<T> {
fn should_resolve(&self, prefix: &str, attrs: &Attributes) -> bool {
match self {
Some(inner) => inner.should_resolve(prefix, attrs),
None => false,
}
}
fn resolve(&mut self, prefix: &str, attrs: &Attributes) {
if let Some(inner) = self {
inner.resolve(prefix, attrs);
}
}
}