vertigo 0.11.3

Reactive Real-DOM library with SSR for Rust
Documentation
use std::rc::Rc;

use crate::{Computed, Css, Value};

#[derive(Clone)]
pub enum AttrValue {
    String(Rc<String>),
    Computed(Computed<String>),
    ComputedOpt(Computed<Option<String>>),
    Value(Value<String>),
    ValueOpt(Value<Option<String>>),
}

impl AttrValue {
    pub fn get(&self, ctx: &crate::computed::context::Context) -> Option<Rc<String>> {
        match self {
            AttrValue::String(s) => Some(s.clone()),
            AttrValue::Computed(c) => Some(Rc::new(c.get(ctx))),
            AttrValue::ComputedOpt(c) => c.get(ctx).map(Rc::new),
            AttrValue::Value(v) => Some(Rc::new(v.get(ctx))),
            AttrValue::ValueOpt(v) => v.get(ctx).map(Rc::new),
        }
    }

    pub fn combine(classes: Vec<AttrValue>) -> AttrValue {
        let mut all_static = true;
        for class in &classes {
            if !matches!(class, AttrValue::String(_)) {
                all_static = false;
                break;
            }
        }

        if all_static {
            let mut result = Vec::new();
            for class in classes {
                if let AttrValue::String(s) = class {
                    let s = s.trim();
                    if !s.is_empty() {
                        result.push(s.to_string());
                    }
                }
            }
            return AttrValue::String(Rc::new(result.join(" ")));
        }

        let computed = crate::Computed::from(move |ctx| {
            let mut result = Vec::new();
            for class in &classes {
                if let Some(s) = class.get(ctx) {
                    let s = s.trim();
                    if !s.is_empty() {
                        result.push(s.to_string());
                    }
                }
            }
            result.join(" ")
        });

        AttrValue::Computed(computed)
    }
}

impl<K: ToString> From<K> for AttrValue {
    fn from(value: K) -> Self {
        AttrValue::String(Rc::new(value.to_string()))
    }
}

macro_rules! impl_from_computed_for_attrvalue {
    ($typename:ty, $variant:ident, |$var:ident| $body:expr) => {
        impl From<$typename> for AttrValue {
            fn from($var: $typename) -> Self {
                AttrValue::$variant($body)
            }
        }
    };
    ($typename: ty, $variant: ident) => {
        impl_from_computed_for_attrvalue!($typename, $variant, |v| v);
    };
}

impl_from_computed_for_attrvalue!(Computed<String>, Computed);
impl_from_computed_for_attrvalue!(Computed<Option<String>>, ComputedOpt);
impl_from_computed_for_attrvalue!(&Computed<String>, Computed, |v| v.clone());
impl_from_computed_for_attrvalue!(&Computed<Option<String>>, ComputedOpt, |v| v.clone());

impl_from_computed_for_attrvalue!(Value<String>, Value);
impl_from_computed_for_attrvalue!(Value<Option<String>>, ValueOpt);
impl_from_computed_for_attrvalue!(&Value<String>, Value, |v| v.clone());
impl_from_computed_for_attrvalue!(&Value<Option<String>>, ValueOpt, |v| v.clone());

macro_rules! impl_stringable_into_computed_for_attrvalue {
    ($typename:ty) => {
        impl_from_computed_for_attrvalue!(Computed<$typename>, Computed, |v| v
            .map(|v| v.to_string()));
        impl_from_computed_for_attrvalue!(&Computed<$typename>, Computed, |v| v
            .map(|v| v.to_string()));
        impl_from_computed_for_attrvalue!(Value<$typename>, Computed, |v| v
            .to_computed()
            .map(|v| v.to_string()));
        impl_from_computed_for_attrvalue!(&Value<$typename>, Computed, |v| v
            .to_computed()
            .map(|v| v.to_string()));
    };
}

impl_stringable_into_computed_for_attrvalue!(i8);
impl_stringable_into_computed_for_attrvalue!(i16);
impl_stringable_into_computed_for_attrvalue!(i32);
impl_stringable_into_computed_for_attrvalue!(i64);
impl_stringable_into_computed_for_attrvalue!(isize);

impl_stringable_into_computed_for_attrvalue!(u8);
impl_stringable_into_computed_for_attrvalue!(u16);
impl_stringable_into_computed_for_attrvalue!(u32);
impl_stringable_into_computed_for_attrvalue!(u64);
impl_stringable_into_computed_for_attrvalue!(usize);

impl_stringable_into_computed_for_attrvalue!(f32);
impl_stringable_into_computed_for_attrvalue!(f64);

impl_stringable_into_computed_for_attrvalue!(char);

impl_stringable_into_computed_for_attrvalue!(bool);

pub enum CssAttrValue {
    Css(Css),
    Computed(Computed<Css>),
}

impl From<Css> for CssAttrValue {
    fn from(value: Css) -> Self {
        CssAttrValue::Css(value)
    }
}

impl From<Computed<Css>> for CssAttrValue {
    fn from(value: Computed<Css>) -> Self {
        CssAttrValue::Computed(value)
    }
}

impl From<&Css> for CssAttrValue {
    fn from(value: &Css) -> Self {
        CssAttrValue::Css(value.clone())
    }
}