1use std::{
2 collections::HashMap,
3 hash::{Hash, Hasher},
4};
5
6use serde::Deserialize;
7
8use crate::Action;
9
10#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
11pub struct State(HashMap<String, i32>);
12
13impl State {
14 pub fn keys(&self) -> impl Iterator<Item = &String> {
15 self.0.keys()
16 }
17
18 pub fn get(&self, key: &str) -> Option<&i32> {
19 self.0.get(key)
20 }
21
22 fn insert(&mut self, key: String, value: i32) {
23 self.0.insert(key, value);
24 }
25
26 pub fn apply(&self, action: &Action) -> Option<Self> {
28 let mut new_props = self.clone();
29 for (key, delta) in &action.deltas {
30 let old_val = *new_props.get(key).unwrap_or(&0);
31 let new_val = old_val + delta;
32 if new_val < 0 {
33 return None;
34 }
35 new_props.insert(key.clone(), new_val);
36 }
37 Some(new_props)
38 }
39}
40
41impl Hash for State {
42 fn hash<H: Hasher>(&self, state: &mut H) {
43 for (key, value) in &self.0 {
45 key.hash(state);
46 value.hash(state);
47 }
48 }
49}