leo_ast/common/
identifier.rs

1// Copyright (C) 2019-2025 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::{Expression, Node, NodeID, simple_node_impl};
18
19use leo_span::{Span, Symbol};
20
21use snarkvm::{console::program::Identifier as IdentifierCore, prelude::Network};
22use std::{
23    fmt,
24    hash::{Hash, Hasher},
25};
26
27use serde::{Deserialize, Serialize};
28
29/// An identifier in a program.
30///
31/// Attention - When adding or removing fields from this struct,
32/// please remember to update its Serialize and Deserialize implementation
33/// to reflect the new struct instantiation.
34#[derive(Clone, Copy, Default, Serialize, Deserialize)]
35pub struct Identifier {
36    /// The symbol that the user wrote, e.g., `foo`.
37    pub name: Symbol,
38    /// A span locating where the identifier occurred in the source.
39    pub span: Span,
40    /// The ID of the node.
41    pub id: NodeID,
42}
43
44simple_node_impl!(Identifier);
45
46impl Identifier {
47    /// Constructs a new identifier with `name` and `id` and a default span.
48    pub fn new(name: Symbol, id: NodeID) -> Self {
49        Self { name, span: Span::default(), id }
50    }
51
52    /// Check if the Identifier name matches the other name.
53    pub fn matches(&self, other: &Self) -> bool {
54        self.name == other.name
55    }
56}
57
58impl fmt::Display for Identifier {
59    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60        self.name.fmt(f)
61    }
62}
63impl fmt::Debug for Identifier {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        self.name.fmt(f)
66    }
67}
68
69impl PartialEq for Identifier {
70    fn eq(&self, other: &Self) -> bool {
71        self.name == other.name && self.span == other.span
72    }
73}
74
75impl Eq for Identifier {}
76
77impl Hash for Identifier {
78    fn hash<H: Hasher>(&self, state: &mut H) {
79        self.name.hash(state);
80        self.span.hash(state);
81    }
82}
83
84impl<N: Network> From<&IdentifierCore<N>> for Identifier {
85    fn from(id: &IdentifierCore<N>) -> Self {
86        Self { name: Symbol::intern(&id.to_string()), span: Default::default(), id: Default::default() }
87    }
88}
89
90impl From<Identifier> for Expression {
91    fn from(value: Identifier) -> Self {
92        Expression::Identifier(value)
93    }
94}