snarkvm_circuit_program/data/access/
mod.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use crate::Identifier;
17use snarkvm_circuit_network::Aleo;
18use snarkvm_circuit_types::{U32, environment::prelude::*};
19
20use std::{
21    fmt,
22    fmt::{Debug, Display, Formatter},
23    str::FromStr,
24};
25
26/// A helper type for accessing an entry in a register, struct, array, or record.
27#[derive(Clone)]
28pub enum Access<A: Aleo> {
29    /// Access a member of a register, struct, or record.
30    Member(Identifier<A>),
31    /// Access an element of an array.
32    Index(U32<A>),
33}
34
35impl<A: Aleo> Inject for Access<A> {
36    type Primitive = console::Access<A::Network>;
37
38    /// Initializes a new access circuit from a primitive.
39    /// Note: Access types are always `Mode::Constant`.
40    fn new(_m: Mode, plaintext: Self::Primitive) -> Self {
41        match plaintext {
42            Self::Primitive::Member(identifier) => Self::Member(Identifier::new(_m, identifier)),
43            Self::Primitive::Index(index) => Self::Index(U32::new(_m, index)),
44        }
45    }
46}
47
48impl<A: Aleo> Eject for Access<A> {
49    type Primitive = console::Access<A::Network>;
50
51    /// Ejects the mode of the access.
52    fn eject_mode(&self) -> Mode {
53        match self {
54            Self::Member(member) => member.eject_mode(),
55            Self::Index(index) => index.eject_mode(),
56        }
57    }
58
59    /// Ejects the access.
60    fn eject_value(&self) -> Self::Primitive {
61        match self {
62            Self::Member(identifier) => console::Access::Member(identifier.eject_value()),
63            Self::Index(index) => console::Access::Index(index.eject_value()),
64        }
65    }
66}
67
68impl<A: Aleo> Parser for Access<A> {
69    /// Parses a UTF-8 string into an access.
70    #[inline]
71    fn parse(string: &str) -> ParserResult<Self> {
72        // Parse the identifier from the string.
73        let (string, access) = console::Access::parse(string)?;
74
75        Ok((string, Access::constant(access)))
76    }
77}
78
79impl<A: Aleo> FromStr for Access<A> {
80    type Err = Error;
81
82    /// Parses a UTF-8 string into an identifier.
83    #[inline]
84    fn from_str(string: &str) -> Result<Self> {
85        match Self::parse(string) {
86            Ok((remainder, object)) => {
87                // Ensure the remainder is empty.
88                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
89                // Return the object.
90                Ok(object)
91            }
92            Err(error) => bail!("Failed to parse string. {error}"),
93        }
94    }
95}
96
97impl<A: Aleo> Debug for Access<A> {
98    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
99        Display::fmt(self, f)
100    }
101}
102
103impl<A: Aleo> Display for Access<A> {
104    /// Prints the identifier as a string.
105    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
106        write!(f, "{}", self.eject_value())
107    }
108}
109
110impl<A: Aleo> Eq for Access<A> {}
111
112impl<A: Aleo> PartialEq for Access<A> {
113    /// Implements the `Eq` trait for the access.
114    fn eq(&self, other: &Self) -> bool {
115        self.eject_value() == other.eject_value()
116    }
117}