1use anyhow::{bail, ensure, Result};
2use serde::{Deserialize, Serialize};
3use std::collections::{BTreeMap, BTreeSet};
4
5#[derive(PartialEq, Eq, Debug, Deserialize, Serialize)]
6pub enum EventKind {
7 Span(i64, Option<u32>),
8 Instant(i64),
9}
10
11#[derive(PartialEq, Eq, Debug, Deserialize, Serialize)]
12pub struct Event {
13 pub fields: BTreeMap<String, String>,
14 pub kind: EventKind,
15 pub value: String,
16 pub tooltip: Option<String>
17}
18
19impl Event {
20 pub fn start_time(&self) -> i64 {
21 match self.kind {
22 EventKind::Span(start, _) => start,
23 EventKind::Instant(instant) => instant,
24 }
25 }
26
27 pub fn end_time(&self) -> Option<i64> {
28 match self.kind {
29 EventKind::Span(start, Some(duration)) => Some(start + duration as i64),
30 EventKind::Span(_, None) => None,
31 EventKind::Instant(instant) => Some(instant),
32 }
33 }
34}
35
36impl Ord for Event {
37 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
38 (self.start_time(), self.end_time()).cmp(&(other.start_time(), other.end_time()))
39 }
40}
41
42impl PartialOrd for Event {
43 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
44 Some(self.cmp(other))
45 }
46}
47
48#[derive(Debug, Deserialize, Serialize)]
49pub struct Actor {
50 pub identity: String,
51 pub tooltip: Option<String>
52}
53
54impl Actor {
55 pub fn new(identity: impl AsRef<str>) -> Self {
56 Self {
57 identity: identity.as_ref().to_owned(),
58 tooltip: None
59 }
60 }
61}
62
63#[derive(Debug, Deserialize, Serialize)]
64pub struct EventStore {
65 actors: BTreeMap<ActorId, Actor>,
66 events: BTreeMap<ActorId, BTreeSet<Event>>,
67}
68
69pub type ActorId = String;
70
71impl EventStore {
72 pub fn register_actor(&mut self, actor: Actor) -> Result<ActorId> {
73 let actor_id = actor.identity.clone();
74 ensure!(
75 self.actors.insert(actor_id.clone(), actor).is_none(),
76 "Actor already registered"
77 );
78 ensure!(self
79 .events
80 .insert(actor_id.clone(), BTreeSet::new())
81 .is_none());
82 Ok(actor_id)
83 }
84
85 pub fn add_event(&mut self, actor: &ActorId, event: Event) -> Result<()> {
86 let Some(events) = self.events.get_mut(actor) else {
87 bail!("Unknown actor id: {}", actor);
88 };
89
90 events.insert(event);
91 Ok(())
92 }
93
94 pub fn all_events(&self) -> impl Iterator<Item = &Event> {
95 self.events.values().flatten()
96 }
97
98 pub fn events_for(&self, actor: &ActorId) -> Result<impl Iterator<Item = &Event>> {
99 let Some(events) = self.events.get(actor) else {
100 bail!("Unknown actor id: {}", actor);
101 };
102
103 Ok(events.iter())
104 }
105
106 pub fn actors<'a>(&'a self) -> impl Iterator<Item = ActorId> + 'a {
107 self.events.keys().cloned()
108 }
109
110 pub fn get_actor(&self, id: &ActorId) -> &Actor {
111 self.actors.get(id).expect("Invalid actor id")
112 }
113}
114
115impl Default for EventStore {
116 fn default() -> Self {
117 Self {
118 actors: BTreeMap::new(),
119 events: BTreeMap::new(),
120 }
121 }
122}