1use crate::{Identifier, Node, NodeID, TypeKind, indent_display::Indent};
18use leo_span::{Span, Symbol};
19use serde::Serialize;
20use std::fmt;
21
22pub use prototypes::{FunctionPrototype, MappingPrototype, RecordPrototype, StorageVariablePrototype};
23
24mod prototypes;
25
26#[derive(Clone, Default, Serialize)]
28pub struct Interface {
29 pub is_exported: Option<bool>,
33 pub identifier: Identifier,
35 pub parents: Vec<(Span, TypeKind)>,
37 pub span: Span,
39 pub id: NodeID,
41 pub functions: Vec<(Symbol, FunctionPrototype)>,
43 pub records: Vec<(Symbol, RecordPrototype)>,
45 pub mappings: Vec<MappingPrototype>,
47 pub storages: Vec<StorageVariablePrototype>,
49}
50
51impl Interface {
52 pub fn name(&self) -> Symbol {
53 self.identifier.name
54 }
55
56 pub fn is_record_type(&self, ty: &TypeKind) -> bool {
58 if let TypeKind::Composite(ct) = ty
59 && let Some(loc) = ct.path.try_global_location()
60 && let Some(&name) = loc.path.first()
61 {
62 return self.records.iter().any(|(n, _)| *n == name);
63 }
64 false
65 }
66}
67
68impl PartialEq for Interface {
69 fn eq(&self, other: &Self) -> bool {
70 self.identifier == other.identifier
71 }
72}
73
74impl Eq for Interface {}
75
76impl fmt::Debug for Interface {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 write!(f, "{self}")
79 }
80}
81
82impl fmt::Display for Interface {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 if self.is_exported == Some(true) {
85 write!(f, "export ")?;
86 }
87 writeln!(
88 f,
89 "interface {}{} {{",
90 self.identifier,
91 if self.parents.is_empty() {
92 String::new()
93 } else {
94 format!(" : {}", self.parents.iter().map(|(_, p)| p.to_string()).collect::<Vec<_>>().join(" + "))
95 }
96 )?;
97 for (_, fun_prot) in &self.functions {
98 writeln!(f, "{}", Indent(fun_prot))?;
99 }
100 for (_, rec_prot) in &self.records {
101 writeln!(f, "{}", Indent(rec_prot))?;
102 }
103 write!(f, "}}")
104 }
105}
106
107crate::simple_node_impl!(Interface);