use crate::{Identifier, Node, NodeID, Type, indent_display::Indent};
use leo_span::{Span, Symbol};
use serde::{Deserialize, Serialize};
use std::fmt;
pub use prototypes::{FunctionPrototype, MappingPrototype, RecordPrototype, StorageVariablePrototype};
mod prototypes;
#[derive(Clone, Default, Serialize, Deserialize)]
pub struct Interface {
pub identifier: Identifier,
pub parents: Vec<(Span, Type)>,
pub span: Span,
pub id: NodeID,
pub functions: Vec<(Symbol, FunctionPrototype)>,
pub records: Vec<(Symbol, RecordPrototype)>,
pub mappings: Vec<MappingPrototype>,
pub storages: Vec<StorageVariablePrototype>,
}
impl Interface {
pub fn name(&self) -> Symbol {
self.identifier.name
}
pub fn is_record_type(&self, ty: &Type) -> bool {
if let Type::Composite(ct) = ty
&& let Some(loc) = ct.path.try_global_location()
&& let Some(&name) = loc.path.first()
{
return self.records.iter().any(|(n, _)| *n == name);
}
false
}
}
impl PartialEq for Interface {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for Interface {}
impl fmt::Debug for Interface {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl fmt::Display for Interface {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(
f,
"interface {}{} {{",
self.identifier,
if self.parents.is_empty() {
String::new()
} else {
format!(" : {}", self.parents.iter().map(|(_, p)| p.to_string()).collect::<Vec<_>>().join(" + "))
}
)?;
for (_, fun_prot) in &self.functions {
writeln!(f, "{}", Indent(fun_prot))?;
}
for (_, rec_prot) in &self.records {
writeln!(f, "{}", Indent(rec_prot))?;
}
write!(f, "}}")
}
}
crate::simple_node_impl!(Interface);