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, Type, indent_display::Indent};
18use leo_span::{Span, Symbol};
19use serde::{Deserialize, 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, Deserialize)]
28pub struct Interface {
29    /// The interface identifier, e.g., `Foo` in `interface Foo { ... }`.
30    pub identifier: Identifier,
31    /// The interfaces this interface inherits from (supports multiple inheritance)
32    pub parents: Vec<(Span, Type)>,
33    /// The entire span of the interface definition.
34    pub span: Span,
35    /// The ID of the node.
36    pub id: NodeID,
37    /// A vector of function prototypes.
38    pub functions: Vec<(Symbol, FunctionPrototype)>,
39    /// A vector of record prototypes.
40    pub records: Vec<(Symbol, RecordPrototype)>,
41    /// A vector of mapping prototypes.
42    pub mappings: Vec<MappingPrototype>,
43    /// A vector of storage variable prototypes.
44    pub storages: Vec<StorageVariablePrototype>,
45}
46
47impl Interface {
48    pub fn name(&self) -> Symbol {
49        self.identifier.name
50    }
51
52    /// Returns `true` if `ty` is a composite type whose name matches a record declared in this interface.
53    pub fn is_record_type(&self, ty: &Type) -> bool {
54        if let Type::Composite(ct) = ty
55            && let Some(loc) = ct.path.try_global_location()
56            && let Some(&name) = loc.path.first()
57        {
58            return self.records.iter().any(|(n, _)| *n == name);
59        }
60        false
61    }
62}
63
64impl PartialEq for Interface {
65    fn eq(&self, other: &Self) -> bool {
66        self.identifier == other.identifier
67    }
68}
69
70impl Eq for Interface {}
71
72impl fmt::Debug for Interface {
73    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74        write!(f, "{self}")
75    }
76}
77
78impl fmt::Display for Interface {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        writeln!(
81            f,
82            "interface {}{} {{",
83            self.identifier,
84            if self.parents.is_empty() {
85                String::new()
86            } else {
87                format!(" : {}", self.parents.iter().map(|(_, p)| p.to_string()).collect::<Vec<_>>().join(" + "))
88            }
89        )?;
90        for (_, fun_prot) in &self.functions {
91            writeln!(f, "{}", Indent(fun_prot))?;
92        }
93        for (_, rec_prot) in &self.records {
94            writeln!(f, "{}", Indent(rec_prot))?;
95        }
96        write!(f, "}}")
97    }
98}
99
100crate::simple_node_impl!(Interface);