Skip to main content

theater_chain/
event.rs

1use serde::{Deserialize, Serialize};
2use sha1::{Digest, Sha1};
3use std::fmt::{Debug, Display, Formatter, Result};
4use std::hash::Hash;
5use wasmtime::component::{ComponentType, Lift, Lower};
6
7pub trait EventType:
8    Display + Debug + Send + Sync + ComponentType + Lift + Lower + Hash + Eq + Clone
9{
10    fn event_type(&self) -> String;
11    fn len(&self) -> usize;
12    fn is_empty(&self) -> bool {
13        self.len() == 0
14    }
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, ComponentType, Lift, Lower, Eq)]
18#[component(record)]
19pub struct Event<D: EventType> {
20    pub hash: Vec<u8>,
21    #[component(name = "parent-hash")]
22    pub parent_hash: Option<Vec<u8>>,
23    pub data: D,
24}
25
26impl<D: EventType> PartialEq for Event<D> {
27    fn eq(&self, other: &Self) -> bool {
28        self.hash == other.hash
29    }
30}
31
32impl<D: EventType> Hash for Event<D> {
33    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
34        self.hash.hash(state);
35    }
36}
37
38impl<D: EventType> Event<D> {
39    pub fn new(parent_hash: Option<Vec<u8>>, data: D) -> Self {
40        // Serialize the event data to compute its hash
41        let mut hasher = Sha1::new();
42        if let Some(ref parent) = parent_hash {
43            hasher.update(parent);
44        }
45        hasher.update(data.to_string().as_bytes());
46        let hash = hasher.finalize().to_vec();
47
48        Self {
49            hash,
50            parent_hash,
51            data,
52        }
53    }
54
55    pub fn verify(&self) -> bool {
56        let mut hasher = Sha1::new();
57        if let Some(ref parent) = self.parent_hash {
58            hasher.update(parent);
59        }
60        hasher.update(self.data.to_string().as_bytes());
61        let computed_hash = hasher.finalize().to_vec();
62        self.hash == computed_hash
63    }
64}
65
66impl<D: EventType> Display for Event<D> {
67    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
68        writeln!(f, "EVENT {}", hex::encode(&self.hash))?;
69        match &self.parent_hash {
70            Some(parent) => writeln!(f, "{}", hex::encode(parent))?,
71            None => writeln!(f, "0000000000000000")?,
72        }
73        writeln!(f, "{}", self.data.event_type())?;
74        writeln!(f, "{}", self.data.len())?;
75        writeln!(f)?;
76        writeln!(f, "{}", self.data)?;
77        writeln!(f)?;
78        Ok(())
79    }
80}