snarkvm_circuit_program/data/literal/
mod.rs

1// Copyright 2024-2025 Aleo Network Foundation
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
16pub use cast::Cast;
17pub use cast_lossy::CastLossy;
18
19mod cast;
20mod cast_lossy;
21mod equal;
22mod from_bits;
23mod size_in_bits;
24mod to_bits;
25mod to_fields;
26mod to_type;
27mod variant;
28
29use snarkvm_circuit_account::Signature;
30use snarkvm_circuit_network::Aleo;
31use snarkvm_circuit_types::prelude::*;
32
33#[cfg(test)]
34use console::LiteralType;
35
36/// The literal enum represents all supported circuit types in snarkVM.
37#[derive(Clone)]
38pub enum Literal<A: Aleo> {
39    /// The Aleo address type.
40    Address(Address<A>),
41    /// The boolean type.
42    Boolean(Boolean<A>),
43    /// The field type (base field).
44    Field(Field<A>),
45    /// The group type (affine).
46    Group(Group<A>),
47    /// The 8-bit signed integer type.
48    I8(I8<A>),
49    /// The 16-bit signed integer type.
50    I16(I16<A>),
51    /// The 32-bit signed integer type.
52    I32(I32<A>),
53    /// The 64-bit signed integer type.
54    I64(I64<A>),
55    /// The 128-bit signed integer type.
56    I128(I128<A>),
57    /// The 8-bit unsigned integer type.
58    U8(U8<A>),
59    /// The 16-bit unsigned integer type.
60    U16(U16<A>),
61    /// The 32-bit unsigned integer type.
62    U32(U32<A>),
63    /// The 64-bit unsigned integer type.
64    U64(U64<A>),
65    /// The 128-bit unsigned integer type.
66    U128(U128<A>),
67    /// The scalar type (scalar field).
68    Scalar(Scalar<A>),
69    /// The signature type.
70    Signature(Box<Signature<A>>),
71    /// The string type.
72    String(StringType<A>),
73}
74
75#[cfg(feature = "console")]
76impl<A: Aleo> Inject for Literal<A> {
77    type Primitive = console::Literal<A::Network>;
78
79    /// Initializes a new literal from a primitive.
80    fn new(mode: Mode, value: Self::Primitive) -> Self {
81        match value {
82            Self::Primitive::Address(address) => Self::Address(Address::new(mode, address)),
83            Self::Primitive::Boolean(boolean) => Self::Boolean(Boolean::new(mode, *boolean)),
84            Self::Primitive::Field(field) => Self::Field(Field::new(mode, field)),
85            Self::Primitive::Group(group) => Self::Group(Group::new(mode, group)),
86            Self::Primitive::I8(i8) => Self::I8(I8::new(mode, i8)),
87            Self::Primitive::I16(i16) => Self::I16(I16::new(mode, i16)),
88            Self::Primitive::I32(i32) => Self::I32(I32::new(mode, i32)),
89            Self::Primitive::I64(i64) => Self::I64(I64::new(mode, i64)),
90            Self::Primitive::I128(i128) => Self::I128(I128::new(mode, i128)),
91            Self::Primitive::U8(u8) => Self::U8(U8::new(mode, u8)),
92            Self::Primitive::U16(u16) => Self::U16(U16::new(mode, u16)),
93            Self::Primitive::U32(u32) => Self::U32(U32::new(mode, u32)),
94            Self::Primitive::U64(u64) => Self::U64(U64::new(mode, u64)),
95            Self::Primitive::U128(u128) => Self::U128(U128::new(mode, u128)),
96            Self::Primitive::Scalar(scalar) => Self::Scalar(Scalar::new(mode, scalar)),
97            Self::Primitive::Signature(signature) => Self::Signature(Box::new(Signature::new(mode, *signature))),
98            Self::Primitive::String(string) => Self::String(StringType::new(mode, string)),
99        }
100    }
101}
102
103#[cfg(feature = "console")]
104impl<A: Aleo> Eject for Literal<A> {
105    type Primitive = console::Literal<A::Network>;
106
107    /// Ejects the mode of the literal.
108    fn eject_mode(&self) -> Mode {
109        match self {
110            Self::Address(literal) => literal.eject_mode(),
111            Self::Boolean(literal) => literal.eject_mode(),
112            Self::Field(literal) => literal.eject_mode(),
113            Self::Group(literal) => literal.eject_mode(),
114            Self::I8(literal) => literal.eject_mode(),
115            Self::I16(literal) => literal.eject_mode(),
116            Self::I32(literal) => literal.eject_mode(),
117            Self::I64(literal) => literal.eject_mode(),
118            Self::I128(literal) => literal.eject_mode(),
119            Self::U8(literal) => literal.eject_mode(),
120            Self::U16(literal) => literal.eject_mode(),
121            Self::U32(literal) => literal.eject_mode(),
122            Self::U64(literal) => literal.eject_mode(),
123            Self::U128(literal) => literal.eject_mode(),
124            Self::Scalar(literal) => literal.eject_mode(),
125            Self::Signature(literal) => literal.eject_mode(),
126            Self::String(literal) => literal.eject_mode(),
127        }
128    }
129
130    /// Ejects the literal into its primitive.
131    fn eject_value(&self) -> Self::Primitive {
132        match self {
133            Self::Address(literal) => Self::Primitive::Address(literal.eject_value()),
134            Self::Boolean(literal) => Self::Primitive::Boolean(console::Boolean::new(literal.eject_value())),
135            Self::Field(literal) => Self::Primitive::Field(literal.eject_value()),
136            Self::Group(literal) => Self::Primitive::Group(literal.eject_value()),
137            Self::I8(literal) => Self::Primitive::I8(literal.eject_value()),
138            Self::I16(literal) => Self::Primitive::I16(literal.eject_value()),
139            Self::I32(literal) => Self::Primitive::I32(literal.eject_value()),
140            Self::I64(literal) => Self::Primitive::I64(literal.eject_value()),
141            Self::I128(literal) => Self::Primitive::I128(literal.eject_value()),
142            Self::U8(literal) => Self::Primitive::U8(literal.eject_value()),
143            Self::U16(literal) => Self::Primitive::U16(literal.eject_value()),
144            Self::U32(literal) => Self::Primitive::U32(literal.eject_value()),
145            Self::U64(literal) => Self::Primitive::U64(literal.eject_value()),
146            Self::U128(literal) => Self::Primitive::U128(literal.eject_value()),
147            Self::Scalar(literal) => Self::Primitive::Scalar(literal.eject_value()),
148            Self::Signature(literal) => Self::Primitive::Signature(Box::new(literal.eject_value())),
149            Self::String(literal) => Self::Primitive::String(literal.eject_value()),
150        }
151    }
152}
153
154#[cfg(feature = "console")]
155impl<A: Aleo> Parser for Literal<A> {
156    /// Parses a string into a literal.
157    #[inline]
158    fn parse(string: &str) -> ParserResult<Self> {
159        alt((
160            map(Address::parse, |literal| Self::Address(literal)),
161            map(Boolean::parse, |literal| Self::Boolean(literal)),
162            map(Field::parse, |literal| Self::Field(literal)),
163            map(Group::parse, |literal| Self::Group(literal)),
164            map(I8::parse, |literal| Self::I8(literal)),
165            map(I16::parse, |literal| Self::I16(literal)),
166            map(I32::parse, |literal| Self::I32(literal)),
167            map(I64::parse, |literal| Self::I64(literal)),
168            map(I128::parse, |literal| Self::I128(literal)),
169            map(U8::parse, |literal| Self::U8(literal)),
170            map(U16::parse, |literal| Self::U16(literal)),
171            map(U32::parse, |literal| Self::U32(literal)),
172            map(U64::parse, |literal| Self::U64(literal)),
173            map(U128::parse, |literal| Self::U128(literal)),
174            map(Scalar::parse, |literal| Self::Scalar(literal)),
175            map(Signature::parse, |literal| Self::Signature(Box::new(literal))),
176            map(StringType::parse, |literal| Self::String(literal)),
177        ))(string)
178    }
179}
180
181#[cfg(feature = "console")]
182impl<A: Aleo> FromStr for Literal<A> {
183    type Err = Error;
184
185    /// Parses a string into a literal circuit.
186    #[inline]
187    fn from_str(string: &str) -> Result<Self> {
188        match Self::parse(string) {
189            Ok((remainder, object)) => {
190                // Ensure the remainder is empty.
191                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
192                // Return the object.
193                Ok(object)
194            }
195            Err(error) => bail!("Failed to parse string. {error}"),
196        }
197    }
198}
199
200#[cfg(feature = "console")]
201impl<A: Aleo> Literal<A> {
202    /// Returns the type name of the literal.
203    pub fn type_name(&self) -> &str {
204        match self {
205            Self::Address(..) => Address::<A>::type_name(),
206            Self::Boolean(..) => Boolean::<A>::type_name(),
207            Self::Field(..) => Field::<A>::type_name(),
208            Self::Group(..) => Group::<A>::type_name(),
209            Self::I8(..) => I8::<A>::type_name(),
210            Self::I16(..) => I16::<A>::type_name(),
211            Self::I32(..) => I32::<A>::type_name(),
212            Self::I64(..) => I64::<A>::type_name(),
213            Self::I128(..) => I128::<A>::type_name(),
214            Self::U8(..) => U8::<A>::type_name(),
215            Self::U16(..) => U16::<A>::type_name(),
216            Self::U32(..) => U32::<A>::type_name(),
217            Self::U64(..) => U64::<A>::type_name(),
218            Self::U128(..) => U128::<A>::type_name(),
219            Self::Scalar(..) => Scalar::<A>::type_name(),
220            Self::Signature(..) => Signature::<A>::type_name(),
221            Self::String(..) => StringType::<A>::type_name(),
222        }
223    }
224}
225
226#[cfg(feature = "console")]
227impl<A: Aleo> Debug for Literal<A> {
228    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
229        Display::fmt(self, f)
230    }
231}
232
233#[cfg(feature = "console")]
234impl<A: Aleo> Display for Literal<A> {
235    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
236        match self {
237            Self::Address(literal) => Display::fmt(literal, f),
238            Self::Boolean(literal) => Display::fmt(literal, f),
239            Self::Field(literal) => Display::fmt(literal, f),
240            Self::Group(literal) => Display::fmt(literal, f),
241            Self::I8(literal) => Display::fmt(literal, f),
242            Self::I16(literal) => Display::fmt(literal, f),
243            Self::I32(literal) => Display::fmt(literal, f),
244            Self::I64(literal) => Display::fmt(literal, f),
245            Self::I128(literal) => Display::fmt(literal, f),
246            Self::U8(literal) => Display::fmt(literal, f),
247            Self::U16(literal) => Display::fmt(literal, f),
248            Self::U32(literal) => Display::fmt(literal, f),
249            Self::U64(literal) => Display::fmt(literal, f),
250            Self::U128(literal) => Display::fmt(literal, f),
251            Self::Scalar(literal) => Display::fmt(literal, f),
252            Self::Signature(literal) => Display::fmt(literal, f),
253            Self::String(literal) => Display::fmt(literal, f),
254        }
255    }
256}