impulse_thaw/input/
rule.rs

1use std::ops::Deref;
2use leptos::prelude::*;
3use crate::{FieldValidationState, Rule};
4
5#[derive(Debug, Default, PartialEq, Clone, Copy)]
6pub enum InputRuleTrigger {
7    #[default]
8    Blur,
9    Focus,
10    Input,
11    Change,
12}
13
14pub struct InputRule(Rule<String, InputRuleTrigger>);
15
16impl InputRule {
17    pub fn required(required: Signal<bool>) -> Self {
18        Self::validator(move |value, name| {
19            if required.get_untracked() && value.is_empty() {
20                let message = name.get_untracked().map_or_else(
21                    || String::from("Please input!"),
22                    |name| format!("Please input {name}!"),
23                );
24                Err(FieldValidationState::Error(message))
25            } else {
26                Ok(())
27            }
28        })
29    }
30
31    pub fn required_with_message(required: Signal<bool>, message: Signal<String>) -> Self {
32        Self::validator(move |value, _| {
33            if required.get_untracked() && value.is_empty() {
34                Err(FieldValidationState::Error(message.get_untracked()))
35            } else {
36                Ok(())
37            }
38        })
39    }
40
41    pub fn validator(
42        f: impl Fn(&String, Signal<Option<String>>) -> Result<(), FieldValidationState>
43            + Send
44            + Sync
45            + 'static,
46    ) -> Self {
47        Self(Rule::validator(f))
48    }
49
50    pub fn with_trigger(self, trigger: InputRuleTrigger) -> Self {
51        Self(Rule::with_trigger(self.0, trigger))
52    }
53}
54
55impl Deref for InputRule {
56    type Target = Rule<String, InputRuleTrigger>;
57
58    fn deref(&self) -> &Self::Target {
59        &self.0
60    }
61}