1use std::fmt;
18
19use crate::{
20 Annotation,
21 ConstParameter,
22 Identifier,
23 Input,
24 Member,
25 Node,
26 NodeID,
27 Output,
28 TupleType,
29 TypeKind,
30 TypeNode,
31 Variant,
32 indent_display::Indent,
33};
34use itertools::Itertools;
35use leo_span::Span;
36use serde::Serialize;
37
38#[derive(Clone, Default, Debug, Serialize)]
40pub struct MappingPrototype {
41 pub identifier: Identifier,
43 pub key_type: TypeKind,
45 pub value_type: TypeKind,
47 pub span: Span,
49 pub id: NodeID,
51}
52
53impl PartialEq for MappingPrototype {
54 fn eq(&self, other: &Self) -> bool {
55 self.identifier == other.identifier
56 }
57}
58
59impl Eq for MappingPrototype {}
60
61impl fmt::Display for MappingPrototype {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 write!(f, "mapping {}: {} => {};", self.identifier, self.key_type, self.value_type)
64 }
65}
66
67crate::simple_node_impl!(MappingPrototype);
68
69#[derive(Clone, Default, Debug, Serialize)]
71pub struct StorageVariablePrototype {
72 pub identifier: Identifier,
74 pub type_: TypeNode,
76 pub span: Span,
78 pub id: NodeID,
80}
81
82impl PartialEq for StorageVariablePrototype {
83 fn eq(&self, other: &Self) -> bool {
84 self.identifier == other.identifier
85 }
86}
87
88impl Eq for StorageVariablePrototype {}
89
90impl fmt::Display for StorageVariablePrototype {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 write!(f, "storage {}: {};", self.identifier, self.type_)
93 }
94}
95
96crate::simple_node_impl!(StorageVariablePrototype);
97
98#[derive(Clone, Default, Serialize)]
99pub struct FunctionPrototype {
100 pub annotations: Vec<Annotation>,
102 pub variant: Variant,
106 pub identifier: Identifier,
108 pub const_parameters: Vec<ConstParameter>,
110 pub input: Vec<Input>,
112 pub output: Vec<Output>,
114 pub output_type: TypeKind,
116 pub span: Span,
118 pub id: NodeID,
120}
121
122impl FunctionPrototype {
123 #[allow(clippy::too_many_arguments)]
124 pub fn new(
125 annotations: Vec<Annotation>,
126 variant: Variant,
127 identifier: Identifier,
128 const_parameters: Vec<ConstParameter>,
129 input: Vec<Input>,
130 output: Vec<Output>,
131 span: Span,
132 id: NodeID,
133 ) -> Self {
134 let output_type = match output.len() {
135 0 => TypeKind::Unit,
136 1 => output[0].type_.kind().clone(),
137 _ => TypeKind::Tuple(TupleType::new(output.iter().map(|o| o.type_.kind().clone()).collect())),
138 };
139
140 Self { annotations, variant, identifier, const_parameters, input, output, output_type, span, id }
141 }
142}
143
144impl PartialEq for FunctionPrototype {
145 fn eq(&self, other: &Self) -> bool {
146 self.identifier == other.identifier
147 }
148}
149
150impl Eq for FunctionPrototype {}
151
152impl fmt::Debug for FunctionPrototype {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 write!(f, "{self}")
155 }
156}
157
158impl fmt::Display for FunctionPrototype {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 for annotation in &self.annotations {
161 writeln!(f, "{annotation}")?;
162 }
163 match self.variant {
164 Variant::View => write!(f, "view fn {}", self.identifier)?,
165 Variant::EntryPoint => write!(f, "fn {}", self.identifier)?,
166 v => panic!(
167 "FunctionPrototype constructed with invalid variant `{v:?}`; only `EntryPoint` or `View` are allowed"
168 ),
169 }
170 if !self.const_parameters.is_empty() {
171 write!(f, "::[{}]", self.const_parameters.iter().format(", "))?;
172 }
173 write!(f, "({})", self.input.iter().format(", "))?;
174 match self.output.len() {
175 0 => {}
176 1 => {
177 if !matches!(self.output[0].type_.kind(), TypeKind::Unit) {
178 write!(f, " -> {}", self.output[0])?;
179 }
180 }
181 _ => {
182 write!(f, " -> ({})", self.output.iter().format(", "))?;
183 }
184 }
185 write!(f, ";")
186 }
187}
188
189crate::simple_node_impl!(FunctionPrototype);
190
191#[derive(Clone, Default, Serialize)]
192pub struct RecordPrototype {
193 pub identifier: Identifier,
195 pub members: Vec<Member>,
197 pub span: Span,
199 pub id: NodeID,
201}
202
203impl PartialEq for RecordPrototype {
204 fn eq(&self, other: &Self) -> bool {
205 self.identifier == other.identifier
206 }
207}
208
209impl Eq for RecordPrototype {}
210
211impl fmt::Debug for RecordPrototype {
212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213 write!(f, "{self}")
214 }
215}
216
217impl fmt::Display for RecordPrototype {
218 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
219 writeln!(f, " record {} {{", self.identifier)?;
220
221 for field in self.members.iter() {
222 writeln!(f, "{},", Indent(field))?;
223 }
224 write!(f, "}}")
225 }
226}
227
228crate::simple_node_impl!(RecordPrototype);