chartr_core/
event.rs

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}