hyperchad_actions 0.1.4

HyperChad actions package
Documentation
use hyperchad_transformer_models::Visibility;
use moosicbox_arb::xml::XmlString;
use quickcheck::{Arbitrary, Gen};

use crate::{
    Action, ActionEffect, ActionTrigger, ActionType, ElementTarget, LogLevel, StyleAction, Target,
};

fn half_g_max(g: &Gen, max: usize) -> Gen {
    Gen::new(std::cmp::min(max, g.size() / 2))
}

impl Arbitrary for ActionTrigger {
    fn arbitrary(g: &mut Gen) -> Self {
        let half_g = &mut half_g_max(g, 10);
        g.choose(&[
            Self::Click,
            Self::ClickOutside,
            Self::Hover,
            Self::Change,
            Self::Immediate,
            Self::Event(XmlString::arbitrary(half_g).0),
        ])
        .unwrap()
        .clone()
    }
}

impl Arbitrary for Target {
    fn arbitrary(g: &mut Gen) -> Self {
        let max = 1;
        match *g.choose(&(0..=max).collect::<Vec<_>>()).unwrap() {
            0 => Self::Literal(XmlString::arbitrary(g).0),
            1 => Self::Ref(XmlString::arbitrary(g).0),
            _ => unreachable!(),
        }
    }
}

impl Arbitrary for ElementTarget {
    fn arbitrary(g: &mut Gen) -> Self {
        let max = 3;
        match *g.choose(&(0..=max).collect::<Vec<_>>()).unwrap() {
            0 => Self::StrId(Arbitrary::arbitrary(g)),
            1 => Self::SelfTarget,
            2 => Self::LastChild,
            3 => Self::Id(usize::arbitrary(g)),
            _ => unreachable!(),
        }
    }
}

impl Arbitrary for StyleAction {
    fn arbitrary(g: &mut Gen) -> Self {
        match *g.choose(&(0..=1).collect::<Vec<_>>()).unwrap() {
            0 => Self::SetVisibility(Visibility::arbitrary(g)),
            1 => Self::SetDisplay(bool::arbitrary(g)),
            _ => unreachable!(),
        }
    }
}

impl Arbitrary for LogLevel {
    fn arbitrary(g: &mut Gen) -> Self {
        *g.choose(&[
            Self::Error,
            Self::Warn,
            Self::Info,
            Self::Debug,
            Self::Trace,
        ])
        .unwrap()
    }
}

#[cfg(feature = "logic")]
impl Arbitrary for crate::logic::CalcValue {
    fn arbitrary(g: &mut Gen) -> Self {
        Self::Visibility {
            target: ElementTarget::arbitrary(g),
        }
    }
}

#[cfg(feature = "logic")]
impl Arbitrary for crate::logic::Value {
    fn arbitrary(g: &mut Gen) -> Self {
        match *g.choose(&(0..=1).collect::<Vec<_>>()).unwrap() {
            0 => Self::Calc(Arbitrary::arbitrary(g)),
            1 => Self::Visibility(Arbitrary::arbitrary(g)),
            _ => unreachable!(),
        }
    }
}

#[cfg(feature = "logic")]
impl Arbitrary for crate::logic::Condition {
    fn arbitrary(g: &mut Gen) -> Self {
        Self::Eq(Arbitrary::arbitrary(g), Arbitrary::arbitrary(g))
    }
}

#[cfg(feature = "logic")]
impl Arbitrary for crate::logic::If {
    fn arbitrary(g: &mut Gen) -> Self {
        Self {
            condition: Arbitrary::arbitrary(g),
            actions: Arbitrary::arbitrary(g),
            else_actions: Arbitrary::arbitrary(g),
        }
    }
}

impl Arbitrary for ActionType {
    fn arbitrary(g: &mut Gen) -> Self {
        let g = &mut half_g_max(g, 10);

        #[cfg(feature = "logic")]
        let max = 4;
        #[cfg(not(feature = "logic"))]
        let max = 3;
        match *g.choose(&(0..=max).collect::<Vec<_>>()).unwrap() {
            0 => Self::Style {
                target: ElementTarget::arbitrary(g),
                action: StyleAction::arbitrary(g),
            },
            1 => Self::Navigate {
                url: XmlString::arbitrary(g).0,
            },
            2 => Self::Log {
                message: XmlString::arbitrary(g).0,
                level: LogLevel::arbitrary(g),
            },
            3 => Self::Custom {
                action: XmlString::arbitrary(g).0,
            },
            #[cfg(feature = "logic")]
            4 => Self::Logic(crate::logic::If::arbitrary(g)),
            _ => unreachable!(),
        }
    }
}

impl Arbitrary for Action {
    fn arbitrary(g: &mut Gen) -> Self {
        let trigger = ActionTrigger::arbitrary(g);

        if let ActionTrigger::Event(name) = &trigger {
            Self {
                trigger: trigger.clone(),
                effect: ActionEffect {
                    action: ActionType::Event {
                        name: name.to_string(),
                        action: Box::new(ActionType::arbitrary(g)),
                    },
                    delay_off: Option::arbitrary(g),
                    throttle: Option::arbitrary(g),
                    unique: Option::arbitrary(g),
                },
            }
        } else {
            Self {
                trigger,
                effect: Arbitrary::arbitrary(g),
            }
        }
    }
}

impl Arbitrary for ActionEffect {
    fn arbitrary(g: &mut Gen) -> Self {
        Self {
            action: Arbitrary::arbitrary(g),
            delay_off: Option::arbitrary(g),
            throttle: Option::arbitrary(g),
            unique: Option::arbitrary(g),
        }
    }
}