leptos_use/utils/filters/
mod.rs1mod debounce;
2mod throttle;
3
4pub use debounce::*;
5pub use throttle::*;
6
7use crate::sendwrap_fn;
8use leptos::prelude::Signal;
9use std::sync::{Arc, Mutex};
10
11macro_rules! ArcFilterFn {
12 ($R:ident) => {
13 Arc<dyn Fn(Arc<dyn Fn() -> $R>) -> Arc<Mutex<Option<$R>>>>
14 }
15}
16
17pub fn create_filter_wrapper<F, R>(
18 filter: ArcFilterFn!(R),
19 func: F,
20) -> impl Fn() -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
21where
22 F: Fn() -> R + Clone + 'static,
23 R: 'static,
24{
25 sendwrap_fn!(move || Arc::clone(&filter)(Arc::new(func.clone())))
26}
27
28pub fn create_filter_wrapper_with_arg<F, Arg, R>(
29 filter: ArcFilterFn!(R),
30 func: F,
31) -> impl Fn(Arg) -> Arc<Mutex<Option<R>>> + Clone + Send + Sync
32where
33 F: Fn(Arg) -> R + Clone + 'static,
34 R: 'static,
35 Arg: Clone + 'static,
36{
37 sendwrap_fn!(move |arg: Arg| {
38 let func = func.clone();
39 Arc::clone(&filter)(Arc::new(move || func(arg.clone())))
40 })
41}
42
43#[derive(Default)]
45pub enum FilterOptions {
46 #[default]
47 None,
48 Debounce {
49 ms: Signal<f64>,
50 options: DebounceOptions,
51 },
52 Throttle {
53 ms: Signal<f64>,
54 options: ThrottleOptions,
55 },
56}
57
58impl FilterOptions {
59 pub fn debounce(ms: impl Into<Signal<f64>>) -> Self {
60 Self::Debounce {
61 ms: ms.into(),
62 options: DebounceOptions::default(),
63 }
64 }
65
66 pub fn throttle(ms: impl Into<Signal<f64>>) -> Self {
67 Self::Throttle {
68 ms: ms.into(),
69 options: ThrottleOptions::default(),
70 }
71 }
72
73 pub fn filter_fn<R>(&self) -> ArcFilterFn!(R)
74 where
75 R: 'static,
76 {
77 match self {
78 FilterOptions::Debounce { ms, options } => Arc::new(debounce_filter(*ms, *options)),
79 FilterOptions::Throttle { ms, options } => Arc::new(throttle_filter(*ms, *options)),
80 FilterOptions::None => {
81 Arc::new(|invoke: Arc<dyn Fn() -> R>| Arc::new(Mutex::new(Some(invoke()))))
82 }
83 }
84 }
85}
86
87#[macro_export]
89macro_rules! filter_builder_methods {
90 (
91 #[$filter_docs:meta]
92 $filter_field_name:ident
93 ) => {
94 #[$filter_docs]
96 pub fn debounce(self, ms: impl Into<Signal<f64>>) -> Self {
98 self.debounce_with_options(ms, DebounceOptions::default())
99 }
100
101 #[$filter_docs]
103 pub fn debounce_with_options(
105 self,
106 ms: impl Into<Signal<f64>>,
107 options: DebounceOptions,
108 ) -> Self {
109 Self {
110 $filter_field_name: FilterOptions::Debounce {
111 ms: ms.into(),
112 options,
113 },
114 ..self
115 }
116 }
117
118 #[$filter_docs]
120 pub fn throttle(self, ms: impl Into<Signal<f64>>) -> Self {
122 self.throttle_with_options(ms, ThrottleOptions::default())
123 }
124
125 #[$filter_docs]
127 pub fn throttle_with_options(
129 self,
130 ms: impl Into<Signal<f64>>,
131 options: ThrottleOptions,
132 ) -> Self {
133 Self {
134 $filter_field_name: FilterOptions::Throttle {
135 ms: ms.into(),
136 options,
137 },
138 ..self
139 }
140 }
141 };
142}