1use crate::mem_use::{MemUsage, MemUser};
2
3use super::{
4 list::list_state::ListState, map::map_state::MapState, ops::Op, text::text_state::TextState,
5};
6
7pub(crate) trait ObjectState: Clone {
8 fn apply_op(&self, op: Op) -> Self {
9 self.apply_ops(Some(op))
10 }
11
12 fn apply_ops<II: IntoIterator<Item = Op>>(&self, ops: II) -> Self {
13 let mut curr = None;
14 for op in ops.into_iter() {
15 curr = Some(curr.as_ref().unwrap_or(self).apply_op(op));
16 }
17 curr.unwrap_or_else(|| self.clone())
18 }
19
20 fn ops_since(&self, other: Option<&Self>) -> Vec<Op>;
21}
22
23#[derive(Clone, Debug)]
24pub(crate) enum AnyObjectState {
25 List(ListState),
26 Text(TextState),
27 Map(MapState),
28}
29
30impl ObjectState for AnyObjectState {
31 fn apply_ops<II: IntoIterator<Item = Op>>(&self, ops: II) -> Self {
32 match self {
33 AnyObjectState::List(list_state) => AnyObjectState::List(list_state.apply_ops(ops)),
34 AnyObjectState::Text(text_state) => AnyObjectState::Text(text_state.apply_ops(ops)),
35 AnyObjectState::Map(map_state) => AnyObjectState::Map(map_state.apply_ops(ops)),
36 }
37 }
38
39 fn ops_since(&self, other: Option<&AnyObjectState>) -> Vec<Op> {
40 match (self, other) {
41 (AnyObjectState::List(list_state), Some(AnyObjectState::List(other_list_state))) => {
42 list_state.ops_since(Some(other_list_state))
43 }
44 (AnyObjectState::List(list_state), None) => list_state.ops_since(None),
45 (AnyObjectState::Text(list_state), Some(AnyObjectState::Text(other_list_state))) => {
46 list_state.ops_since(Some(other_list_state))
47 }
48 (AnyObjectState::Text(list_state), None) => list_state.ops_since(None),
49 (AnyObjectState::Map(map_state), Some(AnyObjectState::Map(other_map_state))) => {
50 map_state.ops_since(Some(other_map_state))
51 }
52 (AnyObjectState::Map(map_state), None) => map_state.ops_since(None),
53 _ => panic!("Invalid pair of object states to compare"),
54 }
55 }
56}
57
58impl MemUser for AnyObjectState {
59 fn mem_use(&self) -> MemUsage {
60 MemUsage::Enum {
61 name: "ObjectState",
62 discriminant: std::mem::size_of::<usize>(),
63 min_size: std::mem::size_of::<AnyObjectState>(),
64 variant: Box::new(match self {
65 AnyObjectState::List(list) => ("List", list.mem_use()),
66 AnyObjectState::Text(text) => ("Text", text.mem_use()),
67 AnyObjectState::Map(map) => ("Map", map.mem_use()),
68 }),
69 }
70 }
71}