leptos_server/
multi_action.rs

1use reactive_graph::{
2    actions::{ArcMultiAction, MultiAction},
3    traits::DefinedAt,
4};
5use server_fn::ServerFn;
6use std::{ops::Deref, panic::Location};
7
8/// An [`ArcMultiAction`] that can be used to call a server function.
9pub struct ArcServerMultiAction<S>
10where
11    S: ServerFn + 'static,
12    S::Output: 'static,
13{
14    inner: ArcMultiAction<S, Result<S::Output, S::Error>>,
15    #[cfg(any(debug_assertions, leptos_debuginfo))]
16    defined_at: &'static Location<'static>,
17}
18
19impl<S> ArcServerMultiAction<S>
20where
21    S: ServerFn + Clone + Send + Sync + 'static,
22    S::Output: Send + Sync + 'static,
23    S::Error: Send + Sync + 'static,
24{
25    /// Creates a new [`ArcMultiAction`] which, when dispatched, will call the server function `S`.
26    #[track_caller]
27    pub fn new() -> Self {
28        Self {
29            inner: ArcMultiAction::new(|input: &S| {
30                S::run_on_client(input.clone())
31            }),
32            #[cfg(any(debug_assertions, leptos_debuginfo))]
33            defined_at: Location::caller(),
34        }
35    }
36}
37
38impl<S> Deref for ArcServerMultiAction<S>
39where
40    S: ServerFn + 'static,
41    S::Output: 'static,
42{
43    type Target = ArcMultiAction<S, Result<S::Output, S::Error>>;
44
45    fn deref(&self) -> &Self::Target {
46        &self.inner
47    }
48}
49
50impl<S> Clone for ArcServerMultiAction<S>
51where
52    S: ServerFn + 'static,
53    S::Output: 'static,
54{
55    fn clone(&self) -> Self {
56        Self {
57            inner: self.inner.clone(),
58            #[cfg(any(debug_assertions, leptos_debuginfo))]
59            defined_at: self.defined_at,
60        }
61    }
62}
63
64impl<S> Default for ArcServerMultiAction<S>
65where
66    S: ServerFn + Clone + Send + Sync + 'static,
67    S::Output: Send + Sync + 'static,
68    S::Error: Send + Sync + 'static,
69{
70    fn default() -> Self {
71        Self::new()
72    }
73}
74
75impl<S> DefinedAt for ArcServerMultiAction<S>
76where
77    S: ServerFn + 'static,
78    S::Output: 'static,
79{
80    fn defined_at(&self) -> Option<&'static Location<'static>> {
81        #[cfg(any(debug_assertions, leptos_debuginfo))]
82        {
83            Some(self.defined_at)
84        }
85        #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
86        {
87            None
88        }
89    }
90}
91
92/// A [`MultiAction`] that can be used to call a server function.
93pub struct ServerMultiAction<S>
94where
95    S: ServerFn + 'static,
96    S::Output: 'static,
97{
98    inner: MultiAction<S, Result<S::Output, S::Error>>,
99    #[cfg(any(debug_assertions, leptos_debuginfo))]
100    defined_at: &'static Location<'static>,
101}
102
103impl<S> From<ServerMultiAction<S>>
104    for MultiAction<S, Result<S::Output, S::Error>>
105where
106    S: ServerFn + 'static,
107    S::Output: 'static,
108{
109    fn from(value: ServerMultiAction<S>) -> Self {
110        value.inner
111    }
112}
113
114impl<S> ServerMultiAction<S>
115where
116    S: ServerFn + Send + Sync + Clone + 'static,
117    S::Output: Send + Sync + 'static,
118    S::Error: Send + Sync + 'static,
119{
120    /// Creates a new [`MultiAction`] which, when dispatched, will call the server function `S`.
121    pub fn new() -> Self {
122        Self {
123            inner: MultiAction::new(|input: &S| {
124                S::run_on_client(input.clone())
125            }),
126            #[cfg(any(debug_assertions, leptos_debuginfo))]
127            defined_at: Location::caller(),
128        }
129    }
130}
131
132impl<S> Clone for ServerMultiAction<S>
133where
134    S: ServerFn + 'static,
135    S::Output: 'static,
136{
137    fn clone(&self) -> Self {
138        *self
139    }
140}
141
142impl<S> Copy for ServerMultiAction<S>
143where
144    S: ServerFn + 'static,
145    S::Output: 'static,
146{
147}
148
149impl<S> Deref for ServerMultiAction<S>
150where
151    S: ServerFn + 'static,
152    S::Output: 'static,
153    S::Error: 'static,
154{
155    type Target = MultiAction<S, Result<S::Output, S::Error>>;
156
157    fn deref(&self) -> &Self::Target {
158        &self.inner
159    }
160}
161
162impl<S> Default for ServerMultiAction<S>
163where
164    S: ServerFn + Clone + Send + Sync + 'static,
165    S::Output: Send + Sync + 'static,
166    S::Error: Send + Sync + 'static,
167{
168    fn default() -> Self {
169        Self::new()
170    }
171}
172
173impl<S> DefinedAt for ServerMultiAction<S>
174where
175    S: ServerFn + 'static,
176    S::Output: 'static,
177{
178    fn defined_at(&self) -> Option<&'static Location<'static>> {
179        #[cfg(any(debug_assertions, leptos_debuginfo))]
180        {
181            Some(self.defined_at)
182        }
183        #[cfg(not(any(debug_assertions, leptos_debuginfo)))]
184        {
185            None
186        }
187    }
188}