feather_tui/trigger.rs
1/// This macro generates a function that takes a reference to a `Box<dyn Any>`
2/// as an argument and returns a `bool`. The function body (`$body`) determines
3/// whether the condition is met.
4///
5/// # Usage
6///
7/// Use for defining functions required to create a `Trigger` object.
8///
9/// # Example
10/// ```
11/// // Define a trigger function that print the argument than evaluate whether the argument is 5
12/// tui_trg_new_trigger_func!(function_name, argument_name, {
13/// let number = *argument_name.downcast_ref::<u32>().unwrap();
14/// println!("{}", number);
15/// return number == 5;
16/// });
17/// ```
18#[macro_export]
19macro_rules! trg_new_trigger_func {
20 ($func_name:ident, $arg_name:ident, $body:block) => {
21 fn $func_name($arg_name: &Box<dyn std::any::Any>) -> bool $body
22 };
23}
24
25/// A generic trigger handler for evaluating conditions based on stored arguments.
26/// `Trigger` allows you to define a condition as a function, associate it with
27/// an argument, and check whether the condition is met.
28///
29/// # Usage
30/// Trigger is use for creating a `Selector` object.
31///
32/// # Example
33///
34/// ```
35/// use feather_tui as tui;
36///
37/// tui::tui_trg_new_trigger_func!(trigger, arg, {
38/// arg.downcast_ref::<u32>().unwrap() == 5
39/// });
40///
41/// let mut trig = tui::trg::Trigger::new(trigger, 5u32);
42///
43/// trig.check(); // Condition is met return True
44/// trig.update_arg(6);
45/// trig.check(); // Condition no longer met return False
46/// ```
47pub struct Trigger {
48 func: fn(&Box<dyn std::any::Any>) -> bool,
49 arg: Box<dyn std::any::Any>,
50}
51
52impl Trigger {
53 pub fn new<T>(func: fn(&Box<dyn std::any::Any>) -> bool, arg: T) -> Self
54 where
55 T: 'static,
56 {
57 Trigger {
58 func,
59 arg: Box::new(arg),
60 }
61 }
62
63 pub fn check(&mut self) -> bool {
64 (self.func)(&self.arg)
65 }
66
67 pub fn update_arg<T>(&mut self, arg: T)
68 where
69 T: 'static
70 {
71 self.arg = Box::new(arg);
72 }
73}