angzarr_client/proto_ext/
books.rs1use crate::proto::{CommandBook, CommandPage, EventBook, EventPage, MergeStrategy, Snapshot};
6
7use super::cover::CoverExt;
8use super::pages::{CommandPageExt, EventPageExt};
9
10pub trait EventBookExt: CoverExt {
14 fn next_sequence(&self) -> u32;
18
19 fn is_empty(&self) -> bool;
21
22 fn last_page(&self) -> Option<&EventPage>;
24
25 fn first_page(&self) -> Option<&EventPage>;
27}
28
29pub fn calculate_next_sequence(pages: &[EventPage], snapshot: Option<&Snapshot>) -> u32 {
34 if let Some(last_page) = pages.last() {
35 last_page.sequence_num() + 1
36 } else {
37 snapshot.map(|s| s.sequence + 1).unwrap_or(0)
38 }
39}
40
41pub fn calculate_set_next_seq(book: &mut EventBook) {
43 book.next_sequence = calculate_next_sequence(&book.pages, book.snapshot.as_ref());
44}
45
46impl EventBookExt for EventBook {
47 fn next_sequence(&self) -> u32 {
48 self.next_sequence
49 }
50
51 fn is_empty(&self) -> bool {
52 self.pages.is_empty()
53 }
54
55 fn last_page(&self) -> Option<&EventPage> {
56 self.pages.last()
57 }
58
59 fn first_page(&self) -> Option<&EventPage> {
60 self.pages.first()
61 }
62}
63
64pub trait CommandBookExt: CoverExt {
68 fn command_sequence(&self) -> u32;
70
71 fn first_command(&self) -> Option<&CommandPage>;
73
74 fn merge_strategy(&self) -> MergeStrategy;
78}
79
80impl CommandBookExt for CommandBook {
81 fn command_sequence(&self) -> u32 {
82 self.pages.first().map(|p| p.sequence_num()).unwrap_or(0)
83 }
84
85 fn first_command(&self) -> Option<&CommandPage> {
86 self.pages.first()
87 }
88
89 fn merge_strategy(&self) -> MergeStrategy {
90 self.pages
91 .first()
92 .map(|p| p.merge_strategy())
93 .unwrap_or(MergeStrategy::MergeCommutative)
94 }
95}