libpetri_debug/
debug_aware_event_store.rs1use std::sync::Arc;
4
5use libpetri_event::event_store::EventStore;
6use libpetri_event::net_event::NetEvent;
7
8use crate::debug_event_store::DebugEventStore;
9
10pub struct DebugAwareEventStore<E: EventStore> {
17 primary: E,
18 debug_store: Arc<DebugEventStore>,
19}
20
21impl<E: EventStore> DebugAwareEventStore<E> {
22 pub fn new(primary: E, debug_store: Arc<DebugEventStore>) -> Self {
24 Self {
25 primary,
26 debug_store,
27 }
28 }
29
30 pub fn primary(&self) -> &E {
32 &self.primary
33 }
34
35 pub fn primary_mut(&mut self) -> &mut E {
37 &mut self.primary
38 }
39
40 pub fn debug_store(&self) -> Arc<DebugEventStore> {
42 Arc::clone(&self.debug_store)
43 }
44}
45
46impl<E: EventStore> EventStore for DebugAwareEventStore<E> {
47 const ENABLED: bool = true;
48
49 fn append(&mut self, event: NetEvent) {
50 self.debug_store.append(event.clone());
52 if E::ENABLED {
54 self.primary.append(event);
55 }
56 }
57
58 fn events(&self) -> &[NetEvent] {
59 if E::ENABLED {
60 self.primary.events()
61 } else {
62 &[]
63 }
64 }
65
66 fn size(&self) -> usize {
67 if E::ENABLED { self.primary.size() } else { 0 }
68 }
69
70 fn is_empty(&self) -> bool {
71 if E::ENABLED {
72 self.primary.is_empty()
73 } else {
74 true
75 }
76 }
77}
78
79impl<E: EventStore> Default for DebugAwareEventStore<E> {
80 fn default() -> Self {
81 Self {
82 primary: E::default(),
83 debug_store: Arc::new(DebugEventStore::new("default".into())),
84 }
85 }
86}
87
88impl<E: EventStore> std::fmt::Debug for DebugAwareEventStore<E>
89where
90 E: std::fmt::Debug,
91{
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 f.debug_struct("DebugAwareEventStore")
94 .field("primary", &self.primary)
95 .field("debug_store", &self.debug_store)
96 .finish()
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use libpetri_event::event_store::{InMemoryEventStore, NoopEventStore};
104 use std::sync::Arc as StdArc;
105
106 fn exec_started(ts: u64) -> NetEvent {
107 NetEvent::ExecutionStarted {
108 net_name: StdArc::from("test"),
109 timestamp: ts,
110 }
111 }
112
113 #[test]
114 fn delegates_to_both_stores() {
115 let debug_store = Arc::new(DebugEventStore::new("s1".into()));
116 let mut store =
117 DebugAwareEventStore::new(InMemoryEventStore::new(), Arc::clone(&debug_store));
118
119 store.append(exec_started(100));
120
121 assert_eq!(store.size(), 1);
122 assert_eq!(store.events().len(), 1);
123 assert_eq!(debug_store.size(), 1);
124 }
125
126 #[test]
127 fn delegates_to_debug_even_with_noop_primary() {
128 let debug_store = Arc::new(DebugEventStore::new("s1".into()));
129 let mut store = DebugAwareEventStore::new(NoopEventStore, Arc::clone(&debug_store));
130
131 store.append(exec_started(100));
132
133 assert_eq!(store.size(), 0);
135 assert!(store.is_empty());
136 assert_eq!(debug_store.size(), 1);
138 }
139
140 #[test]
141 fn enabled_is_always_true() {
142 assert!(DebugAwareEventStore::<NoopEventStore>::ENABLED);
143 assert!(DebugAwareEventStore::<InMemoryEventStore>::ENABLED);
144 }
145
146 #[test]
147 fn debug_store_accessible() {
148 let debug_store = Arc::new(DebugEventStore::new("s1".into()));
149 let store = DebugAwareEventStore::new(InMemoryEventStore::new(), Arc::clone(&debug_store));
150 assert_eq!(store.debug_store().session_id(), "s1");
151 }
152}