web3api_wasm_rs/debug/
context.rs

1//! Context stores debug information in a stack, and
2//! prints it in a clear format
3
4#[derive(Clone, Debug)]
5pub struct Context {
6    pub description: String,
7    nodes: Vec<Node>,
8}
9
10impl Context {
11    pub fn new() -> Self {
12        Self {
13            description: "context description not set".to_string(),
14            nodes: vec![],
15        }
16    }
17
18    pub fn with_description(description: &str) -> Self {
19      Self {
20        description: description.to_string(),
21        nodes: vec![],
22      }
23    }
24
25    pub fn is_empty(&self) -> bool {
26        self.nodes.len() == 0
27    }
28
29    pub fn get_length(&self) -> i32 {
30        self.nodes.len() as i32
31    }
32
33    pub fn push(&mut self, node_item: &str, node_type: &str, node_info: &str) {
34        self.nodes.push(Node {
35            node_item: node_item.to_string(),
36            node_type: node_type.to_string(),
37            node_info: node_info.to_string(),
38        });
39    }
40
41    pub fn pop(&mut self) -> String {
42        if self.is_empty() {
43            panic!("Error: tried to pop an item from an empty Context stack");
44        }
45        let node = self.nodes.pop().unwrap();
46        let info = if node.node_info.eq(&String::from("")) {
47            String::from("")
48        } else {
49            format!(" >> {}", node.node_info)
50        };
51
52        format!("{}: {}{}", node.node_item, node.node_type, info)
53    }
54
55    pub fn context_to_string(&self) -> String {
56        self.print_with_tabs(0, 2)
57    }
58
59    pub fn print_with_context(&self, message: &str) -> String {
60        [message, "\n", &self.print_with_tabs(1, 0)].concat()
61    }
62
63    fn print_with_tabs(&self, tabs: i32, size: i32) -> String {
64        let width = (tabs + 1) * size;
65        let pad_start = format!("{:width$}", " ", width = width as usize);
66        let pad_end = format!("\n{:width$}", " ", width = (width + 1) as usize);
67
68        let mut result = String::new();
69        result.push_str(&pad_start);
70
71        let ctx = ["Context: ", &self.description].concat();
72        result.push_str(&ctx);
73
74        if self.is_empty() {
75            result.push_str(&pad_end);
76            result.push_str("context stack is empty");
77            return result;
78        }
79
80        for i in (0..self.get_length() as usize).rev() {
81            let node = &self.nodes[i];
82            result.push_str(&pad_end);
83            let msg = format!(
84                "at {} : {} >> {}",
85                node.node_item, node.node_type, node.node_info
86            );
87            result.push_str(&msg);
88        }
89        result
90    }
91}
92
93#[allow(dead_code)]
94#[derive(Debug, Clone)]
95struct Node {
96    node_item: String,
97    node_type: String,
98    node_info: String,
99}
100
101impl std::fmt::Display for Context {
102    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
103        write!(f, "({}, {:?})", self.description, self.nodes)
104    }
105}