Skip to main content

leo_ast/interface/
mod.rs

1// Copyright (C) 2019-2026 Provable Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17use 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/// An interface definition.
27#[derive(Clone, Default, Serialize)]
28pub struct Interface {
29    /// Whether the `export` keyword was written on this interface. `None` when
30    /// visibility doesn't apply (program-block interfaces, which are always
31    /// reachable).
32    pub is_exported: Option<bool>,
33    /// The interface identifier, e.g., `Foo` in `interface Foo { ... }`.
34    pub identifier: Identifier,
35    /// The interfaces this interface inherits from (supports multiple inheritance)
36    pub parents: Vec<(Span, TypeKind)>,
37    /// The entire span of the interface definition.
38    pub span: Span,
39    /// The ID of the node.
40    pub id: NodeID,
41    /// A vector of function prototypes.
42    pub functions: Vec<(Symbol, FunctionPrototype)>,
43    /// A vector of record prototypes.
44    pub records: Vec<(Symbol, RecordPrototype)>,
45    /// A vector of mapping prototypes.
46    pub mappings: Vec<MappingPrototype>,
47    /// A vector of storage variable prototypes.
48    pub storages: Vec<StorageVariablePrototype>,
49}
50
51impl Interface {
52    pub fn name(&self) -> Symbol {
53        self.identifier.name
54    }
55
56    /// Returns `true` if `ty` is a composite type whose name matches a record declared in this interface.
57    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);