oasis_runtime_sdk/
event.rs

1//! Event types for runtimes.
2use std::collections::BTreeMap;
3
4use oasis_core_runtime::transaction::tags::{Tag, Tags};
5
6/// An event emitted by the runtime.
7///
8/// This trait can be derived:
9/// ```
10/// # #[cfg(feature = "oasis-runtime-sdk-macros")]
11/// # mod example {
12/// # use oasis_runtime_sdk_macros::Event;
13/// const MODULE_NAME: &str = "my-module";
14/// #[derive(Clone, Debug, cbor::Encode, Event)]
15/// #[cbor(untagged)]
16/// #[sdk_event(autonumber)] // `module_name` meta is required if `MODULE_NAME` isn't in scope
17/// enum MyEvent {
18///    Greeting(String),      // autonumbered to 0
19///    #[sdk_event(code = 2)] // manually numbered to 2 (`code` is required if not autonumbering)
20///    DontPanic,
21///    Salutation {           // autonumbered to 1
22///        plural: bool,
23///    }
24/// }
25/// # }
26/// ```
27pub trait Event: Sized + cbor::Encode {
28    /// Name of the module that emitted the event.
29    fn module_name() -> &'static str;
30
31    /// Code uniquely identifying the event.
32    fn code(&self) -> u32;
33
34    /// Converts an event into an event tag.
35    ///
36    /// # Key
37    ///
38    /// ```text
39    /// <module (variable size bytes)> <code (big-endian u32)>
40    /// ```
41    ///
42    /// # Value
43    ///
44    /// CBOR-serialized event value.
45    ///
46    fn into_event_tag(self) -> EventTag {
47        etag_for_event(Self::module_name(), self.code(), cbor::to_value(self))
48    }
49}
50
51impl Event for () {
52    fn module_name() -> &'static str {
53        "(none)"
54    }
55
56    fn code(&self) -> u32 {
57        Default::default()
58    }
59}
60
61/// Generate an EventTag corresponding to the passed event triple.
62pub fn etag_for_event(module_name: &str, code: u32, value: cbor::Value) -> EventTag {
63    EventTag {
64        key: [module_name.as_bytes(), &code.to_be_bytes()]
65            .concat()
66            .to_vec(),
67        value,
68    }
69}
70
71/// A key-value pair representing an emitted event that will be emitted as a tag.
72#[derive(Clone, Debug)]
73pub struct EventTag {
74    pub key: Vec<u8>,
75    pub value: cbor::Value,
76}
77
78/// Event tags with values accumulated by key.
79pub type EventTags = BTreeMap<Vec<u8>, Vec<cbor::Value>>;
80
81/// Provides method for converting event tags into events.
82pub trait IntoTags {
83    fn into_tags(self) -> Tags;
84}
85
86impl IntoTags for EventTags {
87    fn into_tags(self) -> Tags {
88        self.into_iter()
89            .map(|(k, v)| Tag::new(k, cbor::to_vec(v)))
90            .collect()
91    }
92}