truce_core/
custom_state.rs1pub struct StateCursor<'a> {
30 data: &'a [u8],
31 pos: usize,
32}
33
34impl<'a> StateCursor<'a> {
35 #[must_use]
36 pub fn new(data: &'a [u8]) -> Self {
37 Self { data, pos: 0 }
38 }
39
40 #[must_use]
41 pub fn remaining(&self) -> usize {
42 self.data.len().saturating_sub(self.pos)
43 }
44
45 pub fn read_bytes(&mut self, n: usize) -> Option<&'a [u8]> {
46 if self.pos + n > self.data.len() {
47 return None;
48 }
49 let slice = &self.data[self.pos..self.pos + n];
50 self.pos += n;
51 Some(slice)
52 }
53
54 pub fn skip_field(&mut self) -> bool {
63 if let Some(bytes) = self.read_bytes(4) {
65 let len = u32::from_le_bytes(
69 bytes
70 .try_into()
71 .expect("read_bytes(4) returned a slice of unexpected length"),
72 ) as usize;
73 if self.pos + len <= self.data.len() {
74 self.pos += len;
75 return true;
76 }
77 }
78 false
79 }
80}
81
82pub trait StateField: Sized {
86 fn write_field(&self, buf: &mut Vec<u8>);
87 fn read_field(cursor: &mut StateCursor) -> Option<Self>;
88}
89
90pub trait State: Sized + Default {
95 fn serialize_into(&self, buf: &mut Vec<u8>);
100
101 #[must_use]
105 fn serialize(&self) -> Vec<u8> {
106 let mut buf = Vec::new();
107 self.serialize_into(&mut buf);
108 buf
109 }
110
111 fn deserialize(data: &[u8]) -> Option<Self>;
112}
113
114macro_rules! impl_state_field_int {
119 ($($ty:ty),*) => {
120 $(
121 impl StateField for $ty {
122 fn write_field(&self, buf: &mut Vec<u8>) {
123 buf.extend_from_slice(&self.to_le_bytes());
124 }
125 fn read_field(cursor: &mut StateCursor) -> Option<Self> {
126 let bytes = cursor.read_bytes(std::mem::size_of::<Self>())?;
127 Some(Self::from_le_bytes(bytes.try_into().ok()?))
128 }
129 }
130 )*
131 };
132}
133
134impl_state_field_int!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64);
135
136impl StateField for bool {
137 fn write_field(&self, buf: &mut Vec<u8>) {
138 buf.push(u8::from(*self));
139 }
140 fn read_field(cursor: &mut StateCursor) -> Option<Self> {
141 let b = cursor.read_bytes(1)?;
142 Some(b[0] != 0)
143 }
144}
145
146impl StateField for String {
147 fn write_field(&self, buf: &mut Vec<u8>) {
148 let bytes = self.as_bytes();
149 crate::cast::len_u32(bytes.len()).write_field(buf);
150 buf.extend_from_slice(bytes);
151 }
152 fn read_field(cursor: &mut StateCursor) -> Option<Self> {
153 let len = u32::read_field(cursor)? as usize;
154 let bytes = cursor.read_bytes(len)?;
155 String::from_utf8(bytes.to_vec()).ok()
156 }
157}
158
159impl<T: StateField> StateField for Vec<T> {
160 fn write_field(&self, buf: &mut Vec<u8>) {
161 crate::cast::len_u32(self.len()).write_field(buf);
162 for item in self {
163 item.write_field(buf);
164 }
165 }
166 fn read_field(cursor: &mut StateCursor) -> Option<Self> {
167 let len = u32::read_field(cursor)? as usize;
168 let mut vec = Vec::with_capacity(len.min(1024));
169 for _ in 0..len {
170 vec.push(T::read_field(cursor)?);
171 }
172 Some(vec)
173 }
174}
175
176impl<T: StateField> StateField for Option<T> {
177 fn write_field(&self, buf: &mut Vec<u8>) {
178 match self {
179 Some(val) => {
180 1u8.write_field(buf);
181 val.write_field(buf);
182 }
183 None => {
184 0u8.write_field(buf);
185 }
186 }
187 }
188 fn read_field(cursor: &mut StateCursor) -> Option<Self> {
189 let tag = u8::read_field(cursor)?;
190 if tag == 0 {
191 Some(None)
192 } else {
193 Some(Some(T::read_field(cursor)?))
194 }
195 }
196}
197
198use crate::editor::PluginContext;
203use std::sync::Arc;
204
205pub struct StateBinding<T: State> {
229 cached: T,
230 get_state: Arc<dyn Fn() -> Vec<u8> + Send + Sync>,
231 set_state: Arc<dyn Fn(Vec<u8>) + Send + Sync>,
232}
233
234impl<T: State> StateBinding<T> {
235 #[must_use]
240 pub fn new<P: ?Sized>(context: &PluginContext<P>) -> Self {
241 let bridge_for_get = Arc::clone(context.bridge());
242 let bridge_for_set = Arc::clone(context.bridge());
243 let mut binding = Self {
244 cached: T::default(),
245 get_state: Arc::new(move || bridge_for_get.get_state()),
246 set_state: Arc::new(move |data| bridge_for_set.set_state(data)),
247 };
248 binding.sync();
249 binding
250 }
251
252 pub fn sync(&mut self) {
254 let data = (self.get_state)();
255 if !data.is_empty()
256 && let Some(s) = T::deserialize(&data)
257 {
258 self.cached = s;
259 }
260 }
261
262 pub fn get(&self) -> &T {
264 &self.cached
265 }
266
267 pub fn update(&mut self, f: impl FnOnce(&mut T)) {
269 f(&mut self.cached);
270 let data = self.cached.serialize();
271 (self.set_state)(data);
272 }
273}
274
275impl<T: State> Default for StateBinding<T> {
276 fn default() -> Self {
284 Self {
285 cached: T::default(),
286 get_state: Arc::new(Vec::new),
287 set_state: Arc::new(|_| {}),
288 }
289 }
290}
291
292#[cfg(test)]
297mod tests {
298 use super::*;
299
300 #[test]
301 fn primitives_round_trip() {
302 let mut buf = Vec::new();
303 42u32.write_field(&mut buf);
304 2.5f64.write_field(&mut buf);
305 true.write_field(&mut buf);
306
307 let mut cursor = StateCursor::new(&buf);
308 assert_eq!(u32::read_field(&mut cursor), Some(42));
309 assert_eq!(f64::read_field(&mut cursor), Some(2.5));
310 assert_eq!(bool::read_field(&mut cursor), Some(true));
311 }
312
313 #[test]
314 fn string_round_trip() {
315 let mut buf = Vec::new();
316 "hello world".to_string().write_field(&mut buf);
317
318 let mut cursor = StateCursor::new(&buf);
319 assert_eq!(
320 String::read_field(&mut cursor),
321 Some("hello world".to_string())
322 );
323 }
324
325 #[test]
326 fn vec_round_trip() {
327 let mut buf = Vec::new();
328 vec![1u32, 2, 3].write_field(&mut buf);
329
330 let mut cursor = StateCursor::new(&buf);
331 assert_eq!(Vec::<u32>::read_field(&mut cursor), Some(vec![1, 2, 3]));
332 }
333
334 #[test]
335 fn option_round_trip() {
336 let mut buf = Vec::new();
337 Some(42u32).write_field(&mut buf);
338 None::<u32>.write_field(&mut buf);
339
340 let mut cursor = StateCursor::new(&buf);
341 assert_eq!(Option::<u32>::read_field(&mut cursor), Some(Some(42)));
342 assert_eq!(Option::<u32>::read_field(&mut cursor), Some(None));
343 }
344
345 #[test]
346 fn nested_vec_string() {
347 let mut buf = Vec::new();
348 let v = vec!["foo".to_string(), "bar".to_string()];
349 v.write_field(&mut buf);
350
351 let mut cursor = StateCursor::new(&buf);
352 assert_eq!(Vec::<String>::read_field(&mut cursor), Some(v));
353 }
354}