1use cairo_lang_utils::ordered_hash_set::OrderedHashSet;
2use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(transparent)]
8pub struct Contract {
9 items: OrderedHashSet<Item>,
10}
11impl Contract {
12 pub fn from_items(items: OrderedHashSet<Item>) -> Self {
13 Self { items }
14 }
15
16 pub fn json(&self) -> String {
17 serde_json::to_string_pretty(&self).unwrap()
18 }
19
20 pub fn sanity_check(
22 &self,
23 expected_external_count: usize,
24 expected_l1_handler_count: usize,
25 expected_constructor_count: usize,
26 ) {
27 let trait_fn_count: UnorderedHashMap<_, _> = self
28 .items
29 .iter()
30 .filter_map(|item| {
31 let Item::Interface(imp) = item else {
32 return None;
33 };
34 Some((imp.name.clone(), imp.items.len()))
35 })
36 .collect();
37 let mut external_count = 0;
38 let mut l1_handler_count = 0;
39 let mut constructor_count = 0;
40 for item in &self.items {
41 match item {
42 Item::Function(_) => external_count += 1,
43 Item::L1Handler(_) => l1_handler_count += 1,
44 Item::Constructor(_) => constructor_count += 1,
45 Item::Impl(imp) => {
46 external_count += trait_fn_count.get(&imp.interface_name).unwrap_or_else(|| {
47 panic!("Interface `{}` not found in ABI.", imp.interface_name)
48 })
49 }
50 _ => {}
51 }
52 }
53 assert_eq!(external_count, expected_external_count);
54 assert_eq!(l1_handler_count, expected_l1_handler_count);
55 assert_eq!(constructor_count, expected_constructor_count);
56 }
57}
58
59impl IntoIterator for Contract {
60 type Item = Item;
61 type IntoIter = <OrderedHashSet<Item> as IntoIterator>::IntoIter;
62
63 fn into_iter(self) -> Self::IntoIter {
64 self.items.into_iter()
65 }
66}
67
68#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
70#[serde(tag = "type")]
71pub enum Item {
72 #[serde(rename = "function")]
73 Function(Function),
74 #[serde(rename = "constructor")]
75 Constructor(Constructor),
76 #[serde(rename = "l1_handler")]
77 L1Handler(L1Handler),
78 #[serde(rename = "event")]
79 Event(Event),
80 #[serde(rename = "struct")]
81 Struct(Struct),
82 #[serde(rename = "enum")]
83 Enum(Enum),
84 #[serde(rename = "interface")]
85 Interface(Interface),
86 #[serde(rename = "impl")]
87 Impl(Imp),
88}
89
90#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
92pub struct Interface {
93 pub name: String,
94 pub items: Vec<Item>,
95}
96
97#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
99pub struct Imp {
100 pub name: String,
101 pub interface_name: String,
102}
103
104#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
105pub enum StateMutability {
106 #[serde(rename = "external")]
107 External,
108 #[serde(rename = "view")]
109 View,
110}
111
112#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
114pub struct Function {
115 pub name: String,
116 pub inputs: Vec<Input>,
117
118 pub outputs: Vec<Output>,
120 pub state_mutability: StateMutability,
121}
122
123#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
125pub struct Constructor {
126 pub name: String,
127 pub inputs: Vec<Input>,
128}
129
130#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
132pub struct L1Handler {
133 pub name: String,
134 pub inputs: Vec<Input>,
135
136 pub outputs: Vec<Output>,
138 pub state_mutability: StateMutability,
139}
140
141#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
143pub struct Event {
144 pub name: String,
145 #[serde(flatten)]
146 pub kind: EventKind,
147}
148
149#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
151#[serde(tag = "kind")]
152pub enum EventKind {
153 #[serde(rename = "struct")]
154 Struct { members: Vec<EventField> },
155 #[serde(rename = "enum")]
156 Enum { variants: Vec<EventField> },
157}
158
159#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
161pub struct EventField {
162 pub name: String,
163 #[serde(rename = "type")]
164 pub ty: String,
165 pub kind: EventFieldKind,
166}
167
168#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
170pub enum EventFieldKind {
171 #[serde(rename = "key")]
173 KeySerde,
174 #[serde(rename = "data")]
176 DataSerde,
177 #[serde(rename = "nested")]
179 Nested,
180 #[serde(rename = "flat")]
182 Flat,
183}
184
185#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
187pub struct Input {
188 pub name: String,
189 #[serde(rename = "type")]
190 pub ty: String,
191}
192
193#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
195pub struct Output {
196 #[serde(rename = "type")]
197 pub ty: String,
198}
199
200#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
202pub struct Struct {
203 pub name: String,
204 pub members: Vec<StructMember>,
205}
206
207#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
209pub struct StructMember {
210 pub name: String,
211 #[serde(rename = "type")]
212 pub ty: String,
213}
214
215#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
217pub struct Enum {
218 pub name: String,
219 pub variants: Vec<EnumVariant>,
220}
221
222#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
224pub struct EnumVariant {
225 pub name: String,
226 #[serde(rename = "type")]
227 pub ty: String,
228}