1use crate::{
2 model::{Entity, View},
3 resultset::ResultSet,
4};
5use ankurah_proto::Event;
6use std::sync::Arc;
7
8#[derive(Debug, Clone)]
9pub struct EntityChange {
10 pub entity: Arc<Entity>,
11 pub events: Vec<Event>,
12}
13
14#[derive(Debug, Clone)]
15pub enum ItemChange<I> {
16 Initial { item: I },
18 Add { item: I, events: Vec<Event> },
20 Update { item: I, events: Vec<Event> },
22 Remove { item: I, events: Vec<Event> },
24}
25
26impl<I> ItemChange<I> {
27 pub fn entity(&self) -> &I {
28 match self {
29 ItemChange::Initial { item }
30 | ItemChange::Add { item, .. }
31 | ItemChange::Update { item, .. }
32 | ItemChange::Remove { item, .. } => item,
33 }
34 }
35
36 pub fn events(&self) -> &[Event] {
37 match self {
38 ItemChange::Add { events, .. } | ItemChange::Update { events, .. } | ItemChange::Remove { events, .. } => events,
39 _ => &[],
40 }
41 }
42 pub fn kind(&self) -> ChangeKind { ChangeKind::from(self) }
43}
44
45impl<I> std::fmt::Display for ItemChange<I>
46where I: View
47{
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 match self {
50 ItemChange::Initial { item } => {
51 write!(f, "Initial {}/{}", I::collection(), item.id())
52 }
53 ItemChange::Add { item, .. } => {
54 write!(f, "Add {}/{}", I::collection(), item.id())
55 }
56 ItemChange::Update { item, .. } => {
57 write!(f, "Update {}/{}", I::collection(), item.id())
58 }
59 ItemChange::Remove { item, .. } => {
60 write!(f, "Remove {}/{}", I::collection(), item.id())
61 }
62 }
63 }
64}
65
66impl std::fmt::Display for EntityChange {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "EntityChange {}/{}", self.entity.collection, self.entity.id)
69 }
70}
71
72#[derive(Debug)]
73pub struct ChangeSet<R> {
74 pub resultset: crate::resultset::ResultSet<R>,
75 pub changes: Vec<ItemChange<R>>,
76}
77
78impl<I> std::fmt::Display for ChangeSet<I>
79where I: View
80{
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 let results = self.resultset.items.len();
84 write!(f, "ChangeSet({results} results): {}", self.changes.iter().map(|c| c.to_string()).collect::<Vec<_>>().join(", "))
85 }
86}
87
88impl<I> From<ChangeSet<Arc<Entity>>> for ChangeSet<I>
89where I: View
90{
91 fn from(val: ChangeSet<Arc<Entity>>) -> Self {
92 ChangeSet {
93 resultset: ResultSet { items: val.resultset.iter().map(|item| I::from_entity(item.clone())).collect() },
94 changes: val.changes.into_iter().map(|change| change.into()).collect(),
95 }
96 }
97}
98
99impl<I> From<ItemChange<Arc<Entity>>> for ItemChange<I>
100where I: View
101{
102 fn from(change: ItemChange<Arc<Entity>>) -> Self {
103 match change {
104 ItemChange::Initial { item } => ItemChange::Initial { item: I::from_entity(item) },
105 ItemChange::Add { item, events } => ItemChange::Add { item: I::from_entity(item), events },
106 ItemChange::Update { item, events } => ItemChange::Update { item: I::from_entity(item), events },
107 ItemChange::Remove { item, events } => ItemChange::Remove { item: I::from_entity(item), events },
108 }
109 }
110}
111
112#[derive(Debug, Clone, PartialEq)]
113pub enum ChangeKind {
114 Initial,
115 Add,
116 Remove,
117 Update,
118}
119
120impl<R> From<&ItemChange<R>> for ChangeKind {
121 fn from(change: &ItemChange<R>) -> Self {
122 match change {
123 ItemChange::Initial { .. } => ChangeKind::Initial,
124 ItemChange::Add { .. } => ChangeKind::Add,
125 ItemChange::Remove { .. } => ChangeKind::Remove,
126 ItemChange::Update { .. } => ChangeKind::Update,
127 }
128 }
129}