In my rust project, I'm trying to make a db like implementation that can store the state of a user from different integrations that all implement same functions through a trait, and can be written to a file later using serde with this code:
#[derive(Serialize, Deserialize, Debug)]
pub struct State {
pub current: HashMap<Bytes, Box<dyn UserState>>
pub changes: HashMap<u64, Vec<UserStateChange>>
}
pub trait UserState {
fn id(&self) -> Bytes;
fn apply_change(&mut self, change: UserStateChange);
}
#[derive(Serialize, Deserialize, Debug)]
pub enum UserStateChange {
Foo(FooChange),
Bar(BarChange)
}
#[derive(Serialize, Deserialize, Debug)]
pub struct FooState {
id: Bytes,
count: u64,
start: u64
}
#[derive(Serialize, Deserialize, Debug)]
pub struct FooChange {
count_delta: i64
}
impl UserState for FooState {
fn id(&self) -> Bytes {self.id.clone()}
fb apply_change(&mut self, change: UserStateChange) {
let UserStateChange::Foo(change) = change;
todo!();
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BarState {
id: Bytes,
attempts: u64
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BarChange {
attempt_delta: i64
}
impl UserState for BarState {
fn id(&self) -> Bytes {self.id.clone()}
fb apply_change(&mut self, change: UserStateChange) {
let UserStateChange::Bar(change) = change;
// apply logic
}
}
How can I make it so that it can store and serialize the dynamic trait, while ensuring that it supports the apply_change
function, and can use its own structure for storing changes with relevant fields?