reifydb_codec/row/operator/
state.rs1use std::{cell::RefCell, collections::BTreeMap, mem};
5
6use postcard::{from_bytes, to_extend};
7use reifydb_value::{
8 error::{Error as ValueError, TypeError},
9 value::datetime::DateTime,
10};
11use serde::{Serialize, de::DeserializeOwned};
12use thiserror::Error;
13
14use crate::row::pod::EncodedPodRow;
15
16#[derive(Debug, Error, PartialEq)]
17pub enum StateError {
18 #[error("operator state serialization failed: {0}")]
19 Serialization(String),
20
21 #[error("operator state deserialization failed: {0}")]
22 Deserialization(String),
23}
24
25impl From<StateError> for ValueError {
26 fn from(err: StateError) -> Self {
27 match err {
28 StateError::Serialization(_) => TypeError::SerdeSerialize {
29 message: err.to_string(),
30 }
31 .into(),
32 StateError::Deserialization(_) => TypeError::SerdeDeserialize {
33 message: err.to_string(),
34 }
35 .into(),
36 }
37 }
38}
39
40pub trait OperatorState: Sized + Send + 'static {
41 fn encode_state(&self) -> Result<EncodedPodRow, StateError>;
42
43 fn decode_state(row: &EncodedPodRow) -> Result<Self, StateError>;
44}
45
46thread_local! {
47 static ENCODE_BUFFER: RefCell<Vec<u8>> = const { RefCell::new(Vec::new()) };
48}
49
50pub fn encode<T>(value: &T) -> Result<EncodedPodRow, StateError>
51where
52 T: Serialize,
53{
54 let mut buffer = ENCODE_BUFFER.with(|cell| mem::take(&mut *cell.borrow_mut()));
55 buffer.clear();
56 let mut filled = to_extend(value, buffer).map_err(|e| StateError::Serialization(e.to_string()))?;
57 let result = EncodedPodRow::new(&filled);
58 filled.clear();
59 ENCODE_BUFFER.with(|cell| *cell.borrow_mut() = filled);
60 Ok(result)
61}
62
63pub fn decode_body<T>(row: &EncodedPodRow) -> Result<T, StateError>
64where
65 T: DeserializeOwned,
66{
67 from_bytes(row.body()).map_err(|e| StateError::Deserialization(e.to_string()))
68}
69
70pub fn decode<T: OperatorState>(row: &EncodedPodRow) -> Result<T, StateError> {
71 T::decode_state(row)
72}
73
74pub mod derive {
75 pub use serde::{self, Deserialize, Serialize};
76}
77
78pub trait StateCodec: Sized + Send + 'static + Serialize + DeserializeOwned {}
79
80impl<T> StateCodec for T where T: Sized + Send + 'static + Serialize + DeserializeOwned {}
81
82macro_rules! leaf_operator_state {
83 ($($ty:ty),* $(,)?) => {
84 $(impl OperatorState for $ty {
85 fn encode_state(&self) -> Result<EncodedPodRow, StateError> {
86 encode(self)
87 }
88
89 fn decode_state(row: &EncodedPodRow) -> Result<Self, StateError> {
90 decode_body::<Self>(row)
91 }
92 })*
93 };
94}
95
96leaf_operator_state!(u64, i64, Vec<u8>, (i64, i64, i64), DateTime);
97
98impl<K, V> OperatorState for BTreeMap<K, V>
99where
100 K: Send + 'static,
101 V: Send + 'static,
102 Self: Serialize + DeserializeOwned,
103{
104 fn encode_state(&self) -> Result<EncodedPodRow, StateError> {
105 encode(self)
106 }
107
108 fn decode_state(row: &EncodedPodRow) -> Result<Self, StateError> {
109 decode_body::<Self>(row)
110 }
111}