1use dremoc_sync::watch::{channel, Receiver, Sender};
2use remoc::{codec, RemoteSend};
3use serde::{Deserialize, Serialize};
4use std::fmt::{Debug, Display};
5
6pub trait Stateful {
7 type StateSet;
8
9 fn get_state(&self) -> &Self::StateSet;
10 fn get_state_mut(&mut self) -> &mut Self::StateSet;
11}
12
13pub struct State<
14 T,
15 const READ: bool = true,
16 const WRITE: bool = true,
17 const WATCH: bool = true,
18 Codec = codec::Default,
19> {
20 value: T,
21 watch: Option<Box<Sender<T, Codec>>>,
22}
23
24impl<T, const READ: bool, const WRITE: bool, Codec> State<T, READ, WRITE, false, Codec> {
25 pub fn new(value: T) -> Self {
26 Self { value, watch: None }
27 }
28
29 pub fn to_unwatched(self) -> Self {
30 self
31 }
32}
33
34impl<T: RemoteSend + Clone, const READ: bool, const WRITE: bool, Codec>
35 State<T, READ, WRITE, false, Codec>
36{
37 pub fn to_watched(self) -> State<T, READ, WRITE, true, Codec> {
38 self.into()
39 }
40}
41
42impl<T: Default, const READ: bool, const WRITE: bool, Codec> Default
43 for State<T, READ, WRITE, false, Codec>
44{
45 fn default() -> Self {
46 Self::new(T::default())
47 }
48}
49
50impl<T: RemoteSend + Clone, const READ: bool, const WRITE: bool, Codec>
51 State<T, READ, WRITE, true, Codec>
52{
53 pub fn new(value: T) -> Self {
54 let (tx, _) = channel(value.clone());
55 Self {
56 value,
57 watch: Some(Box::new(tx)),
58 }
59 }
60
61 pub fn to_watched(self) -> Self {
62 self
63 }
64}
65
66impl<T, const READ: bool, const WRITE: bool, Codec> State<T, READ, WRITE, true, Codec> {
67 pub fn to_unwatched(self) -> State<T, READ, WRITE, false, Codec> {
68 self.into()
69 }
70}
71
72impl<T: Default + RemoteSend + Clone, const READ: bool, const WRITE: bool, Codec> Default
73 for State<T, READ, WRITE, true, Codec>
74{
75 fn default() -> Self {
76 Self::new(T::default())
77 }
78}
79
80impl<T: Debug, const READ: bool, const WRITE: bool, const WATCH: bool, Codec> Debug
81 for State<T, READ, WRITE, WATCH, Codec>
82{
83 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 self.value.fmt(f)
85 }
86}
87
88impl<T: Display, const READ: bool, const WRITE: bool, const WATCH: bool, Codec> Display
89 for State<T, READ, WRITE, WATCH, Codec>
90{
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 self.value.fmt(f)
93 }
94}
95
96impl<T: Clone, const READ: bool, const WRITE: bool, Codec> Clone
97 for State<T, READ, WRITE, false, Codec>
98{
99 fn clone(&self) -> Self {
100 Self::new(self.value.clone())
101 }
102}
103
104impl<T: RemoteSend + Clone + Clone, const READ: bool, const WRITE: bool, Codec> Clone
105 for State<T, READ, WRITE, true, Codec>
106{
107 fn clone(&self) -> Self {
108 Self::new(self.value.clone())
109 }
110}
111
112impl<T, const READ: bool, const WRITE: bool, const WATCH: bool, Codec> std::ops::Deref
113 for State<T, READ, WRITE, WATCH, Codec>
114{
115 type Target = T;
116
117 #[inline(always)]
118 fn deref(&self) -> &Self::Target {
119 &self.get()
120 }
121}
122
123impl<T, const READ: bool, const WRITE: bool, const WATCH: bool, Codec>
124 State<T, READ, WRITE, WATCH, Codec>
125{
126 #[inline(always)]
127 pub fn get(&self) -> &T {
128 &self.value
129 }
130}
131
132impl<T, const READ: bool, const WRITE: bool, Codec> State<T, READ, WRITE, false, Codec> {
133 #[inline(always)]
134 pub fn set(&mut self, value: T) {
135 self.value = value;
136 }
137
138 #[inline(always)]
139 pub fn modify(&mut self, f: impl FnOnce(&mut T)) {
140 f(&mut self.value);
141 }
142}
143
144impl<T: Clone + Send + 'static, const READ: bool, const WRITE: bool, Codec>
145 State<T, READ, WRITE, true, Codec>
146{
147 #[inline(always)]
148 pub fn set(&mut self, value: T) {
149 self.value = value;
150 self.send_value();
151 }
152
153 #[inline(always)]
154 pub fn modify(&mut self, f: impl FnOnce(&mut T)) {
155 f(&mut self.value);
156 self.send_value();
157 }
158
159 pub fn subscribe(&self) -> Receiver<T, Codec> {
160 self.watch.as_ref().unwrap().subscribe()
161 }
162
163 #[inline(always)]
164 fn send_value(&mut self) {
165 let watch = self.watch.as_ref().unwrap();
166 if !watch.is_closed() {
167 let _ = watch.send(self.value.clone());
168 }
169 }
170}
171
172impl<T: Clone, const WRITE: bool, const WATCH: bool, Codec> State<T, true, WRITE, WATCH, Codec> {
173 #[inline(always)]
174 pub fn remote_get(&self) -> T {
175 self.get().clone()
176 }
177}
178
179impl<T, const READ: bool, Codec> State<T, READ, true, false, Codec> {
180 #[inline(always)]
181 pub fn remote_set(&mut self, value: T) {
182 self.set(value);
183 }
184}
185
186impl<T: Clone + Send + 'static, const READ: bool, Codec> State<T, READ, true, true, Codec> {
187 #[inline(always)]
188 pub fn remote_set(&mut self, value: T) {
189 self.set(value);
190 }
191}
192
193impl<T: Serialize, const READ: bool, const WRITE: bool, Codec> Serialize
194 for State<T, READ, WRITE, false, Codec>
195{
196 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
197 self.value.serialize(serializer)
198 }
199}
200
201impl<T: RemoteSend + Clone + Sync, const READ: bool, const WRITE: bool, Codec: codec::Codec>
202 Serialize for State<T, READ, WRITE, true, Codec>
203{
204 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
205 let mut struct_serializer = serde::Serializer::serialize_struct(serializer, "State", 2)?;
206 serde::ser::SerializeStruct::serialize_field(&mut struct_serializer, "value", &self.value)?;
207 serde::ser::SerializeStruct::serialize_field(
208 &mut struct_serializer,
209 "watch",
210 self.watch.as_ref().unwrap(),
211 )?;
212
213 serde::ser::SerializeStruct::end(struct_serializer)
214 }
215}
216
217impl<'de, T: Deserialize<'de>, const READ: bool, const WRITE: bool, Codec> Deserialize<'de>
218 for State<T, READ, WRITE, false, Codec>
219{
220 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
221 T::deserialize(deserializer).map(Self::new)
222 }
223}
224
225impl<
226 'de,
227 T: RemoteSend + Clone + Sync,
228 const READ: bool,
229 const WRITE: bool,
230 Codec: codec::Codec,
231 > Deserialize<'de> for State<T, READ, WRITE, true, Codec>
232{
233 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
234 where
235 D: serde::Deserializer<'de>,
236 {
237 #[derive(Deserialize)]
238 #[serde(bound(deserialize = "T: RemoteSend, Codec: codec::Codec"))]
239 struct StateDeserializer<T: Clone + Sync, Codec> {
240 value: T,
241 watch: Sender<T, Codec>,
242 }
243
244 let StateDeserializer { value, watch } = serde::Deserialize::deserialize(deserializer)?;
245 Ok(Self {
246 value: value,
247 watch: Some(Box::new(watch)),
248 })
249 }
250}
251
252impl<T: RemoteSend + Clone, const READ: bool, const WRITE: bool, Codec>
253 Into<State<T, READ, WRITE, true, Codec>> for State<T, READ, WRITE, false, Codec>
254{
255 fn into(self) -> State<T, READ, WRITE, true, Codec> {
256 State::<T, READ, WRITE, true, Codec>::new(self.value)
257 }
258}
259
260impl<T, const READ: bool, const WRITE: bool, Codec> Into<State<T, READ, WRITE, false, Codec>>
261 for State<T, READ, WRITE, true, Codec>
262{
263 fn into(self) -> State<T, READ, WRITE, false, Codec> {
264 State::<T, READ, WRITE, false, Codec>::new(self.value)
265 }
266}