zng_var/var_impl/
response_var.rs1use crate::{AnyVar, Var};
4
5use super::*;
6
7pub fn response_var<T: VarValue>() -> (ResponderVar<T>, ResponseVar<T>) {
9 let responder = var(Response::Waiting::<T>);
10 let response = responder.read_only();
11 (ResponderVar(responder), ResponseVar(response))
12}
13
14pub fn response_done_var<T: VarValue>(response: T) -> ResponseVar<T> {
16 ResponseVar(var(Response::Done(response)).read_only())
17}
18
19#[derive(Clone)]
23pub struct ResponderVar<T: VarValue>(Var<Response<T>>);
24
25#[derive(Clone)]
29pub struct ResponseVar<T: VarValue>(Var<Response<T>>);
30
31impl<T: VarValue> ops::Deref for ResponderVar<T> {
32 type Target = Var<Response<T>>;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38impl<T: VarValue> IntoVar<Response<T>> for ResponderVar<T> {
39 fn into_var(self) -> Var<Response<T>> {
40 self.0
41 }
42}
43impl<T: VarValue> From<ResponderVar<T>> for Var<Response<T>> {
44 fn from(var: ResponderVar<T>) -> Self {
45 var.0
46 }
47}
48impl<T: VarValue> From<ResponderVar<T>> for AnyVar {
49 fn from(var: ResponderVar<T>) -> Self {
50 var.0.into()
51 }
52}
53
54impl<T: VarValue> ops::Deref for ResponseVar<T> {
55 type Target = Var<Response<T>>;
56
57 fn deref(&self) -> &Self::Target {
58 &self.0
59 }
60}
61impl<T: VarValue> IntoVar<Response<T>> for ResponseVar<T> {
62 fn into_var(self) -> Var<Response<T>> {
63 self.0
64 }
65}
66impl<T: VarValue> From<ResponseVar<T>> for Var<Response<T>> {
67 fn from(var: ResponseVar<T>) -> Self {
68 var.0
69 }
70}
71impl<T: VarValue> From<ResponseVar<T>> for AnyVar {
72 fn from(var: ResponseVar<T>) -> Self {
73 var.0.into()
74 }
75}
76
77#[derive(Clone, Copy, PartialEq)]
79pub enum Response<T: VarValue> {
80 Waiting,
82 Done(T),
84}
85impl<T: VarValue> Response<T> {
86 pub fn is_done(&self) -> bool {
88 matches!(self, Response::Done(_))
89 }
90
91 pub fn is_waiting(&self) -> bool {
93 matches!(self, Response::Waiting)
94 }
95
96 pub fn done(&self) -> Option<&T> {
98 match self {
99 Response::Waiting => None,
100 Response::Done(r) => Some(r),
101 }
102 }
103}
104impl<T: VarValue> fmt::Debug for Response<T> {
105 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106 if f.alternate() {
107 match self {
108 Response::Waiting => {
109 write!(f, "Response::Waiting")
110 }
111 Response::Done(v) => f.debug_tuple("Response::Done").field(v).finish(),
112 }
113 } else {
114 match self {
115 Response::Waiting => {
116 write!(f, "Waiting")
117 }
118 Response::Done(v) => fmt::Debug::fmt(v, f),
119 }
120 }
121 }
122}
123impl<T: VarValue> From<Response<T>> for Option<T> {
124 fn from(value: Response<T>) -> Self {
125 match value {
126 Response::Waiting => None,
127 Response::Done(r) => Some(r),
128 }
129 }
130}
131impl<T: VarValue> From<Response<Option<T>>> for Option<T> {
132 fn from(value: Response<Option<T>>) -> Self {
133 match value {
134 Response::Waiting => None,
135 Response::Done(r) => r,
136 }
137 }
138}
139
140impl<T: VarValue> ResponseVar<T> {
141 pub fn with_rsp<R>(&self, read: impl FnOnce(&T) -> R) -> Option<R> {
143 self.with(|value| match value {
144 Response::Waiting => None,
145 Response::Done(value) => Some(read(value)),
146 })
147 }
148
149 pub fn with_new_rsp<R>(&self, read: impl FnOnce(&T) -> R) -> Option<R> {
151 self.with_new(|value| match value {
152 Response::Waiting => None,
153 Response::Done(value) => Some(read(value)),
154 })
155 .flatten()
156 }
157
158 pub fn is_done(&self) -> bool {
160 self.with(Response::is_done)
161 }
162
163 pub fn is_waiting(&self) -> bool {
165 self.with(Response::is_waiting)
166 }
167
168 pub fn rsp(&self) -> Option<T> {
170 self.with_rsp(Clone::clone)
171 }
172
173 pub async fn wait_rsp(&self) -> T {
175 self.wait_done().await;
176 self.rsp().unwrap()
177 }
178
179 pub async fn wait_done(&self) {
183 self.wait_match(Response::is_done).await;
184 }
185
186 pub fn rsp_new(&self) -> Option<T> {
188 self.with_new_rsp(Clone::clone)
189 }
190
191 pub fn map_rsp<O, I, M>(&self, waiting_value: I, map: M) -> Var<O>
193 where
194 O: VarValue,
195 I: Fn() -> O + Send + Sync + 'static,
196 M: FnOnce(&T) -> O + Send + 'static,
197 {
198 let mut map = Some(map);
199 self.filter_map(
200 move |r| match r {
201 Response::Waiting => None,
202 Response::Done(r) => map.take().map(|m| m(r)),
203 },
204 waiting_value,
205 )
206 }
207
208 pub fn map_response<O, M>(&self, mut map: M) -> ResponseVar<O>
210 where
211 O: VarValue,
212 M: FnMut(&T) -> O + Send + 'static,
213 {
214 ResponseVar(self.map(move |r| match r {
215 Response::Waiting => Response::Waiting,
216 Response::Done(t) => Response::Done(map(t)),
217 }))
218 }
219}
220impl<T: VarValue> IntoFuture for ResponseVar<T> {
221 type Output = T;
222
223 type IntoFuture = std::pin::Pin<Box<dyn Future<Output = T> + Send + Sync>>;
225
226 fn into_future(self) -> Self::IntoFuture {
227 Box::pin(async move { self.wait_rsp().await })
228 }
229}
230
231impl<T: VarValue> ResponderVar<T> {
232 pub fn respond(&self, response: T) {
234 self.set(Response::Done(response));
235 }
236
237 pub fn response_var(&self) -> ResponseVar<T> {
239 ResponseVar(self.read_only())
240 }
241}