Skip to main content

levi_core/entities/
log_entry.rs

1use myko::prelude::*;
2
3/// Hub transport wrapper for one levi event. id = the event's content address
4/// (git blob OID of its CBOR bytes); payload = base64(CBOR(MEvent)). Immutable
5/// and add-only, so "what are you missing" between a CLI and the hub is a set
6/// difference over LogEntry ids. A hub-side saga unwraps the inner event so
7/// dashboards query real entities.
8#[myko_item]
9pub struct LogEntry {
10    pub project_id: String,
11    pub cbor_b64: String,
12    /// RFC3339 of the inner event (for activity-feed ordering).
13    pub created: String,
14}
15
16impl LogEntry {
17    /// Wrap an event for hub transport. `event_id` must be the event's
18    /// content address (git blob OID of `cbor_bytes`).
19    pub fn wrap(event_id: &str, project_id: &str, cbor_bytes: &[u8], created: &str) -> Self {
20        use base64::Engine as _;
21        LogEntry {
22            id: event_id.into(),
23            project_id: project_id.into(),
24            cbor_b64: base64::engine::general_purpose::STANDARD.encode(cbor_bytes),
25            created: created.into(),
26        }
27    }
28
29    /// Decode back to raw CBOR bytes.
30    pub fn cbor_bytes(&self) -> anyhow::Result<Vec<u8>> {
31        use base64::Engine as _;
32        Ok(base64::engine::general_purpose::STANDARD.decode(&self.cbor_b64)?)
33    }
34
35    /// Decode the inner wire event.
36    pub fn unwrap_event(&self) -> anyhow::Result<myko::wire::MEvent> {
37        Ok(ciborium::from_reader(self.cbor_bytes()?.as_slice())?)
38    }
39}