1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::{address::Address, block_id::BlockId, operation::OperationId, slot::Slot};
use serde::{Deserialize, Serialize};
use std::{collections::VecDeque, fmt::Display};

#[derive(Debug, Clone, Serialize, Deserialize)]
/// By product of a byte code execution
pub struct SCOutputEvent {
    /// context generated by the execution context
    pub context: EventExecutionContext,
    /// json data string
    pub data: String,
}

impl Display for SCOutputEvent {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "Context: {}", self.context)?;
        writeln!(f, "Data: {}", self.data)
    }
}

/// Context of the event (not generated by the user)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventExecutionContext {
    /// when was it generated
    pub slot: Slot,
    /// block id if there was a block at that slot
    pub block: Option<BlockId>,
    /// if the event was generated during a read only execution
    pub read_only: bool,
    /// index of the event in the slot
    pub index_in_slot: u64,
    /// most recent at the end
    pub call_stack: VecDeque<Address>,
    /// origin operation id
    pub origin_operation_id: Option<OperationId>,
    /// if the event is final
    pub is_final: bool,
    /// if the sc that emitted this event failed
    pub is_error: bool,
}

impl Display for EventExecutionContext {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "Slot: {} at index: {}", self.slot, self.index_in_slot)?;

        writeln!(
            f,
            "{}",
            if self.read_only {
                "Read only execution"
            } else {
                "On chain execution"
            }
        )?;
        if let Some(id) = self.block {
            writeln!(f, "Block id: {}", id)?;
        }
        if let Some(id) = self.origin_operation_id {
            writeln!(f, "Origin operation id: {}", id)?;
        }
        writeln!(
            f,
            "Call stack: {}",
            self.call_stack
                .iter()
                .map(|a| format!("{}", a))
                .collect::<Vec<_>>()
                .join(",")
        )
    }
}