dremoc_service/
state.rs

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}