use crate::v18::ActorError;
use crate::v18::cbor::serialize_vec;
use fvm_shared4::event::{ActorEvent, Entry, Flags};
use serde::ser;
const IPLD_CBOR: u64 = 0x51;
const EVENT_TYPE_KEY: &str = "$type";
pub struct EventBuilder {
entries: Result<Vec<Entry>, ActorError>,
}
impl EventBuilder {
pub fn new() -> Self {
Self {
entries: Ok(Vec::new()),
}
}
pub fn typ(self, _type: &str) -> Self {
self.push_entry(EVENT_TYPE_KEY, _type, Flags::FLAG_INDEXED_ALL)
}
pub fn field<T: ser::Serialize + ?Sized>(self, name: &str, value: &T) -> Self {
self.push_entry(name, value, Flags::FLAG_INDEXED_KEY)
}
pub fn field_indexed<T: ser::Serialize + ?Sized>(self, name: &str, value: &T) -> Self {
self.push_entry(name, value, Flags::FLAG_INDEXED_ALL)
}
pub fn build(self) -> Result<ActorEvent, ActorError> {
Ok(ActorEvent {
entries: self.entries?,
})
}
fn push_entry<T: ser::Serialize + ?Sized>(
mut self,
key: &str,
value: &T,
flags: Flags,
) -> Self {
if let Ok(ref mut entries) = self.entries {
match serialize_vec(&value, "event value") {
Ok(value) => entries.push(Entry {
flags,
key: key.to_string(),
codec: IPLD_CBOR,
value,
}),
Err(e) => {
self.entries = Err(e);
}
}
}
self
}
}
impl Default for EventBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod test {
use crate::v18::EventBuilder;
use crate::v18::cbor::serialize_vec;
use crate::v18::util::events::{EVENT_TYPE_KEY, IPLD_CBOR};
use fvm_shared4::event::{ActorEvent, Entry, Flags};
#[test]
fn event_type() {
let e = EventBuilder::new()
.typ("l1")
.field_indexed("v1", "abc")
.build()
.unwrap();
let l1_cbor = serialize_vec("l1", "event value").unwrap();
let v_cbor = serialize_vec("abc", "event value").unwrap();
assert_eq!(
ActorEvent {
entries: vec![
Entry {
flags: Flags::FLAG_INDEXED_ALL,
key: EVENT_TYPE_KEY.to_string(),
codec: IPLD_CBOR,
value: l1_cbor, },
Entry {
flags: Flags::FLAG_INDEXED_ALL,
key: "v1".to_string(),
codec: IPLD_CBOR,
value: v_cbor, },
]
},
e
)
}
#[test]
fn values() {
let e = EventBuilder::new()
.field("v1", &3)
.field_indexed("v2", "abc")
.build()
.unwrap();
assert_eq!(
ActorEvent {
entries: vec![
Entry {
flags: Flags::FLAG_INDEXED_KEY,
key: "v1".to_string(),
codec: IPLD_CBOR,
value: vec![0x03],
},
Entry {
flags: Flags::FLAG_INDEXED_ALL,
key: "v2".to_string(),
codec: IPLD_CBOR,
value: vec![0x63, 0x61, 0x62, 0x63], },
]
},
e
);
}
}