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 Type,
30 Variant,
31 indent_display::Indent,
32};
33use itertools::Itertools;
34use leo_span::Span;
35use serde::{Deserialize, Serialize};
36
37#[derive(Clone, Default, Debug, Serialize, Deserialize)]
39pub struct MappingPrototype {
40 pub identifier: Identifier,
42 pub key_type: Type,
44 pub value_type: Type,
46 pub span: Span,
48 pub id: NodeID,
50}
51
52impl PartialEq for MappingPrototype {
53 fn eq(&self, other: &Self) -> bool {
54 self.identifier == other.identifier
55 }
56}
57
58impl Eq for MappingPrototype {}
59
60impl fmt::Display for MappingPrototype {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 write!(f, "mapping {}: {} => {};", self.identifier, self.key_type, self.value_type)
63 }
64}
65
66crate::simple_node_impl!(MappingPrototype);
67
68#[derive(Clone, Default, Debug, Serialize, Deserialize)]
70pub struct StorageVariablePrototype {
71 pub identifier: Identifier,
73 pub type_: Type,
75 pub span: Span,
77 pub id: NodeID,
79}
80
81impl PartialEq for StorageVariablePrototype {
82 fn eq(&self, other: &Self) -> bool {
83 self.identifier == other.identifier
84 }
85}
86
87impl Eq for StorageVariablePrototype {}
88
89impl fmt::Display for StorageVariablePrototype {
90 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91 write!(f, "storage {}: {};", self.identifier, self.type_)
92 }
93}
94
95crate::simple_node_impl!(StorageVariablePrototype);
96
97#[derive(Clone, Default, Serialize, Deserialize)]
98pub struct FunctionPrototype {
99 pub annotations: Vec<Annotation>,
101 pub variant: Variant,
105 pub identifier: Identifier,
107 pub const_parameters: Vec<ConstParameter>,
109 pub input: Vec<Input>,
111 pub output: Vec<Output>,
113 pub output_type: Type,
115 pub span: Span,
117 pub id: NodeID,
119}
120
121impl FunctionPrototype {
122 #[allow(clippy::too_many_arguments)]
123 pub fn new(
124 annotations: Vec<Annotation>,
125 variant: Variant,
126 identifier: Identifier,
127 const_parameters: Vec<ConstParameter>,
128 input: Vec<Input>,
129 output: Vec<Output>,
130 span: Span,
131 id: NodeID,
132 ) -> Self {
133 let output_type = match output.len() {
134 0 => Type::Unit,
135 1 => output[0].type_.clone(),
136 _ => Type::Tuple(TupleType::new(output.iter().map(|o| o.type_.clone()).collect())),
137 };
138
139 Self { annotations, variant, identifier, const_parameters, input, output, output_type, span, id }
140 }
141}
142
143impl PartialEq for FunctionPrototype {
144 fn eq(&self, other: &Self) -> bool {
145 self.identifier == other.identifier
146 }
147}
148
149impl Eq for FunctionPrototype {}
150
151impl fmt::Debug for FunctionPrototype {
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 write!(f, "{self}")
154 }
155}
156
157impl fmt::Display for FunctionPrototype {
158 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159 for annotation in &self.annotations {
160 writeln!(f, "{annotation}")?;
161 }
162 match self.variant {
163 Variant::View => write!(f, "view fn {}", self.identifier)?,
164 Variant::EntryPoint => write!(f, "fn {}", self.identifier)?,
165 v => panic!(
166 "FunctionPrototype constructed with invalid variant `{v:?}`; only `EntryPoint` or `View` are allowed"
167 ),
168 }
169 if !self.const_parameters.is_empty() {
170 write!(f, "::[{}]", self.const_parameters.iter().format(", "))?;
171 }
172 write!(f, "({})", self.input.iter().format(", "))?;
173 match self.output.len() {
174 0 => {}
175 1 => {
176 if !matches!(self.output[0].type_, Type::Unit) {
177 write!(f, " -> {}", self.output[0])?;
178 }
179 }
180 _ => {
181 write!(f, " -> ({})", self.output.iter().format(", "))?;
182 }
183 }
184 write!(f, ";")
185 }
186}
187
188crate::simple_node_impl!(FunctionPrototype);
189
190#[derive(Clone, Default, Serialize, Deserialize)]
191pub struct RecordPrototype {
192 pub identifier: Identifier,
194 pub members: Vec<Member>,
196 pub span: Span,
198 pub id: NodeID,
200}
201
202impl PartialEq for RecordPrototype {
203 fn eq(&self, other: &Self) -> bool {
204 self.identifier == other.identifier
205 }
206}
207
208impl Eq for RecordPrototype {}
209
210impl fmt::Debug for RecordPrototype {
211 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
212 write!(f, "{self}")
213 }
214}
215
216impl fmt::Display for RecordPrototype {
217 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
218 writeln!(f, " record {} {{", self.identifier)?;
219
220 for field in self.members.iter() {
221 writeln!(f, "{},", Indent(field))?;
222 }
223 write!(f, "}}")
224 }
225}
226
227crate::simple_node_impl!(RecordPrototype);