use std::fmt;
use crate::{
Annotation,
ConstParameter,
Identifier,
Input,
Member,
Node,
NodeID,
Output,
TupleType,
Type,
indent_display::Indent,
};
use itertools::Itertools;
use leo_span::Span;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct MappingPrototype {
pub identifier: Identifier,
pub key_type: Type,
pub value_type: Type,
pub span: Span,
pub id: NodeID,
}
impl PartialEq for MappingPrototype {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for MappingPrototype {}
impl fmt::Display for MappingPrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "mapping {}: {} => {};", self.identifier, self.key_type, self.value_type)
}
}
crate::simple_node_impl!(MappingPrototype);
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct StorageVariablePrototype {
pub identifier: Identifier,
pub type_: Type,
pub span: Span,
pub id: NodeID,
}
impl PartialEq for StorageVariablePrototype {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for StorageVariablePrototype {}
impl fmt::Display for StorageVariablePrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "storage {}: {};", self.identifier, self.type_)
}
}
crate::simple_node_impl!(StorageVariablePrototype);
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct FunctionPrototype {
pub annotations: Vec<Annotation>,
pub identifier: Identifier,
pub const_parameters: Vec<ConstParameter>,
pub input: Vec<Input>,
pub output: Vec<Output>,
pub output_type: Type,
pub span: Span,
pub id: NodeID,
}
impl FunctionPrototype {
#[allow(clippy::too_many_arguments)]
pub fn new(
annotations: Vec<Annotation>,
identifier: Identifier,
const_parameters: Vec<ConstParameter>,
input: Vec<Input>,
output: Vec<Output>,
span: Span,
id: NodeID,
) -> Self {
let output_type = match output.len() {
0 => Type::Unit,
1 => output[0].type_.clone(),
_ => Type::Tuple(TupleType::new(output.iter().map(|o| o.type_.clone()).collect())),
};
Self { annotations, identifier, const_parameters, input, output, output_type, span, id }
}
}
impl PartialEq for FunctionPrototype {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for FunctionPrototype {}
impl fmt::Debug for FunctionPrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl fmt::Display for FunctionPrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for annotation in &self.annotations {
writeln!(f, "{annotation}")?;
}
write!(f, "fn {}", self.identifier)?;
if !self.const_parameters.is_empty() {
write!(f, "::[{}]", self.const_parameters.iter().format(", "))?;
}
write!(f, "({})", self.input.iter().format(", "))?;
match self.output.len() {
0 => {}
1 => {
if !matches!(self.output[0].type_, Type::Unit) {
write!(f, " -> {}", self.output[0])?;
}
}
_ => {
write!(f, " -> ({})", self.output.iter().format(", "))?;
}
}
write!(f, ";")
}
}
crate::simple_node_impl!(FunctionPrototype);
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct RecordPrototype {
pub identifier: Identifier,
pub members: Vec<Member>,
pub span: Span,
pub id: NodeID,
}
impl PartialEq for RecordPrototype {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for RecordPrototype {}
impl fmt::Debug for RecordPrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl fmt::Display for RecordPrototype {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, " record {} {{", self.identifier)?;
for field in self.members.iter() {
writeln!(f, "{},", Indent(field))?;
}
write!(f, "}}")
}
}
crate::simple_node_impl!(RecordPrototype);