Skip to main content

teaql_runtime/
event.rs

1use std::sync::Arc;
2
3use teaql_core::{Record, Value};
4
5use crate::{RuntimeError, UserContext};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum EntityEventKind {
9    Created,
10    Updated,
11    Deleted,
12    Recovered,
13}
14
15#[derive(Debug, Clone, PartialEq)]
16pub struct EntityEvent {
17    pub kind: EntityEventKind,
18    pub entity: String,
19    pub values: Record,
20    pub updated_fields: Vec<String>,
21}
22
23impl EntityEvent {
24    pub fn created(entity: impl Into<String>, values: Record) -> Self {
25        Self {
26            kind: EntityEventKind::Created,
27            entity: entity.into(),
28            values,
29            updated_fields: Vec::new(),
30        }
31    }
32
33    pub fn updated(entity: impl Into<String>, values: Record) -> Self {
34        let updated_fields = values.keys().cloned().collect();
35        Self {
36            kind: EntityEventKind::Updated,
37            entity: entity.into(),
38            values,
39            updated_fields,
40        }
41    }
42
43    pub fn deleted(entity: impl Into<String>, id: Value, expected_version: Option<i64>) -> Self {
44        let mut values = Record::from([("id".to_owned(), id)]);
45        if let Some(version) = expected_version {
46            values.insert("version".to_owned(), Value::I64(version));
47        }
48        Self {
49            kind: EntityEventKind::Deleted,
50            entity: entity.into(),
51            values,
52            updated_fields: Vec::new(),
53        }
54    }
55
56    pub fn recovered(entity: impl Into<String>, id: Value, expected_version: i64) -> Self {
57        Self {
58            kind: EntityEventKind::Recovered,
59            entity: entity.into(),
60            values: Record::from([
61                ("id".to_owned(), id),
62                ("version".to_owned(), Value::I64(expected_version)),
63            ]),
64            updated_fields: Vec::new(),
65        }
66    }
67}
68
69pub trait EntityEventSink: Send + Sync {
70    fn on_event(&self, ctx: &UserContext, event: &EntityEvent) -> Result<(), RuntimeError>;
71}
72
73#[derive(Default, Clone)]
74pub struct InMemoryEntityEventSink {
75    sinks: Vec<Arc<dyn EntityEventSink>>,
76}
77
78impl InMemoryEntityEventSink {
79    pub fn new() -> Self {
80        Self::default()
81    }
82
83    pub fn register(&mut self, sink: impl EntityEventSink + 'static) {
84        self.sinks.push(Arc::new(sink));
85    }
86
87    pub fn with_sink(mut self, sink: impl EntityEventSink + 'static) -> Self {
88        self.register(sink);
89        self
90    }
91}
92
93impl EntityEventSink for InMemoryEntityEventSink {
94    fn on_event(&self, ctx: &UserContext, event: &EntityEvent) -> Result<(), RuntimeError> {
95        for sink in &self.sinks {
96            sink.on_event(ctx, event)?;
97        }
98        Ok(())
99    }
100}