starknet_abigen_parser_stopgap/
cairo_event.rs

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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! Event parsing.
use starknet::core::types::contract::{AbiEvent, AbiNamedMember, EventFieldKind, TypedAbiEvent};

use super::abi_types::{AbiType, AbiTypeAny};
use super::{CairoEnum, CairoStruct};

#[derive(Debug, Clone)]
pub enum CairoEventInner {
    Enum(CairoEnum),
    Struct(CairoStruct),
}

#[derive(Debug, Clone)]
pub struct CairoEvent {
    pub abi: AbiTypeAny,
    pub inner: CairoEventInner,
    pub fields_kinds: Vec<EventFieldKind>,
}

impl CairoEvent {
    /// Gets the name of the struct type.
    pub fn get_name(&self) -> String {
        self.abi.get_cairo_type_name()
    }

    /// Gets the count for each field kind (keys, data).
    pub fn count_fields_kinds(&self) -> (usize, usize) {
        let mut k = 0;
        let mut d = 0;

        for fk in &self.fields_kinds {
            match fk {
                EventFieldKind::Key => k += 1,
                EventFieldKind::Data => d += 1,
                _ => continue,
            }
        }

        (k, d)
    }

    /// Initializes a new instance from the abi name and it's members.
    pub fn new(abi_event: &AbiEvent) -> Option<CairoEvent> {
        match abi_event {
            AbiEvent::Typed(typed_e) => match typed_e {
                TypedAbiEvent::Struct(s) => {
                    if s.members.is_empty() {
                        return None;
                    }

                    let name = &s.name;
                    let mut kinds = vec![];
                    let members = s
                        .members
                        .iter()
                        .map(|m| {
                            kinds.push(m.kind.clone());
                            AbiNamedMember {
                                name: m.name.clone(),
                                r#type: m.r#type.clone(),
                            }
                        })
                        .collect();

                    let cs = CairoStruct::new(name, &members);

                    Some(CairoEvent {
                        abi: AbiTypeAny::from_string(name),
                        inner: CairoEventInner::Struct(cs),
                        fields_kinds: kinds,
                    })
                }
                TypedAbiEvent::Enum(e) => {
                    if e.variants.is_empty() {
                        return None;
                    }

                    let name = &e.name;
                    let mut kinds = vec![];
                    let variants = e
                        .variants
                        .iter()
                        .map(|v| {
                            kinds.push(v.kind.clone());
                            AbiNamedMember {
                                name: v.name.clone(),
                                r#type: v.r#type.clone(),
                            }
                        })
                        .collect();

                    let ce = CairoEnum::new(name, &variants);

                    Some(CairoEvent {
                        abi: AbiTypeAny::from_string(name),
                        inner: CairoEventInner::Enum(ce),
                        fields_kinds: kinds,
                    })
                }
            },
            AbiEvent::Untyped(_) => {
                // Can we support this..?
                //panic!("Untyped events are not supported");
                None
            }
        }
    }
}