snarkvm_circuit_program/data/literal/
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
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
75macro_rules! impl_from {
76    ($($name: ident)*) => {
77        $(
78            impl<A: Aleo> From<$name<A>> for Literal<A> {
79                fn from(value: $name<A>) -> Self {
80                    Literal::$name(value)
81                }
82            }
83        )*
84    };
85}
86
87impl_from! {
88    Address Boolean Field Group
89    I8 I16 I32 I64 I128
90    U8 U16 U32 U64 U128
91    Scalar
92}
93
94impl<A: Aleo> From<Signature<A>> for Literal<A> {
95    fn from(value: Signature<A>) -> Self {
96        Literal::Signature(Box::new(value))
97    }
98}
99
100impl<A: Aleo> Inject for Literal<A> {
101    type Primitive = console::Literal<A::Network>;
102
103    /// Initializes a new literal from a primitive.
104    fn new(mode: Mode, value: Self::Primitive) -> Self {
105        match value {
106            Self::Primitive::Address(address) => Self::Address(Address::new(mode, address)),
107            Self::Primitive::Boolean(boolean) => Self::Boolean(Boolean::new(mode, *boolean)),
108            Self::Primitive::Field(field) => Self::Field(Field::new(mode, field)),
109            Self::Primitive::Group(group) => Self::Group(Group::new(mode, group)),
110            Self::Primitive::I8(i8) => Self::I8(I8::new(mode, i8)),
111            Self::Primitive::I16(i16) => Self::I16(I16::new(mode, i16)),
112            Self::Primitive::I32(i32) => Self::I32(I32::new(mode, i32)),
113            Self::Primitive::I64(i64) => Self::I64(I64::new(mode, i64)),
114            Self::Primitive::I128(i128) => Self::I128(I128::new(mode, i128)),
115            Self::Primitive::U8(u8) => Self::U8(U8::new(mode, u8)),
116            Self::Primitive::U16(u16) => Self::U16(U16::new(mode, u16)),
117            Self::Primitive::U32(u32) => Self::U32(U32::new(mode, u32)),
118            Self::Primitive::U64(u64) => Self::U64(U64::new(mode, u64)),
119            Self::Primitive::U128(u128) => Self::U128(U128::new(mode, u128)),
120            Self::Primitive::Scalar(scalar) => Self::Scalar(Scalar::new(mode, scalar)),
121            Self::Primitive::Signature(signature) => Self::Signature(Box::new(Signature::new(mode, *signature))),
122            Self::Primitive::String(string) => Self::String(StringType::new(mode, string)),
123        }
124    }
125}
126
127impl<A: Aleo> Eject for Literal<A> {
128    type Primitive = console::Literal<A::Network>;
129
130    /// Ejects the mode of the literal.
131    fn eject_mode(&self) -> Mode {
132        match self {
133            Self::Address(literal) => literal.eject_mode(),
134            Self::Boolean(literal) => literal.eject_mode(),
135            Self::Field(literal) => literal.eject_mode(),
136            Self::Group(literal) => literal.eject_mode(),
137            Self::I8(literal) => literal.eject_mode(),
138            Self::I16(literal) => literal.eject_mode(),
139            Self::I32(literal) => literal.eject_mode(),
140            Self::I64(literal) => literal.eject_mode(),
141            Self::I128(literal) => literal.eject_mode(),
142            Self::U8(literal) => literal.eject_mode(),
143            Self::U16(literal) => literal.eject_mode(),
144            Self::U32(literal) => literal.eject_mode(),
145            Self::U64(literal) => literal.eject_mode(),
146            Self::U128(literal) => literal.eject_mode(),
147            Self::Scalar(literal) => literal.eject_mode(),
148            Self::Signature(literal) => literal.eject_mode(),
149            Self::String(literal) => literal.eject_mode(),
150        }
151    }
152
153    /// Ejects the literal into its primitive.
154    fn eject_value(&self) -> Self::Primitive {
155        match self {
156            Self::Address(literal) => Self::Primitive::Address(literal.eject_value()),
157            Self::Boolean(literal) => Self::Primitive::Boolean(console::Boolean::new(literal.eject_value())),
158            Self::Field(literal) => Self::Primitive::Field(literal.eject_value()),
159            Self::Group(literal) => Self::Primitive::Group(literal.eject_value()),
160            Self::I8(literal) => Self::Primitive::I8(literal.eject_value()),
161            Self::I16(literal) => Self::Primitive::I16(literal.eject_value()),
162            Self::I32(literal) => Self::Primitive::I32(literal.eject_value()),
163            Self::I64(literal) => Self::Primitive::I64(literal.eject_value()),
164            Self::I128(literal) => Self::Primitive::I128(literal.eject_value()),
165            Self::U8(literal) => Self::Primitive::U8(literal.eject_value()),
166            Self::U16(literal) => Self::Primitive::U16(literal.eject_value()),
167            Self::U32(literal) => Self::Primitive::U32(literal.eject_value()),
168            Self::U64(literal) => Self::Primitive::U64(literal.eject_value()),
169            Self::U128(literal) => Self::Primitive::U128(literal.eject_value()),
170            Self::Scalar(literal) => Self::Primitive::Scalar(literal.eject_value()),
171            Self::Signature(literal) => Self::Primitive::Signature(Box::new(literal.eject_value())),
172            Self::String(literal) => Self::Primitive::String(literal.eject_value()),
173        }
174    }
175}
176
177impl<A: Aleo> Parser for Literal<A> {
178    /// Parses a string into a literal.
179    #[inline]
180    fn parse(string: &str) -> ParserResult<Self> {
181        alt((
182            map(Address::parse, |literal| Self::Address(literal)),
183            map(Boolean::parse, |literal| Self::Boolean(literal)),
184            map(Field::parse, |literal| Self::Field(literal)),
185            map(Group::parse, |literal| Self::Group(literal)),
186            map(I8::parse, |literal| Self::I8(literal)),
187            map(I16::parse, |literal| Self::I16(literal)),
188            map(I32::parse, |literal| Self::I32(literal)),
189            map(I64::parse, |literal| Self::I64(literal)),
190            map(I128::parse, |literal| Self::I128(literal)),
191            map(U8::parse, |literal| Self::U8(literal)),
192            map(U16::parse, |literal| Self::U16(literal)),
193            map(U32::parse, |literal| Self::U32(literal)),
194            map(U64::parse, |literal| Self::U64(literal)),
195            map(U128::parse, |literal| Self::U128(literal)),
196            map(Scalar::parse, |literal| Self::Scalar(literal)),
197            map(Signature::parse, |literal| Self::Signature(Box::new(literal))),
198            map(StringType::parse, |literal| Self::String(literal)),
199        ))(string)
200    }
201}
202
203impl<A: Aleo> FromStr for Literal<A> {
204    type Err = Error;
205
206    /// Parses a string into a literal circuit.
207    #[inline]
208    fn from_str(string: &str) -> Result<Self> {
209        match Self::parse(string) {
210            Ok((remainder, object)) => {
211                // Ensure the remainder is empty.
212                ensure!(remainder.is_empty(), "Failed to parse string. Found invalid character in: \"{remainder}\"");
213                // Return the object.
214                Ok(object)
215            }
216            Err(error) => bail!("Failed to parse string. {error}"),
217        }
218    }
219}
220
221impl<A: Aleo> Literal<A> {
222    /// Returns the type name of the literal.
223    pub fn type_name(&self) -> &str {
224        match self {
225            Self::Address(..) => Address::<A>::type_name(),
226            Self::Boolean(..) => Boolean::<A>::type_name(),
227            Self::Field(..) => Field::<A>::type_name(),
228            Self::Group(..) => Group::<A>::type_name(),
229            Self::I8(..) => I8::<A>::type_name(),
230            Self::I16(..) => I16::<A>::type_name(),
231            Self::I32(..) => I32::<A>::type_name(),
232            Self::I64(..) => I64::<A>::type_name(),
233            Self::I128(..) => I128::<A>::type_name(),
234            Self::U8(..) => U8::<A>::type_name(),
235            Self::U16(..) => U16::<A>::type_name(),
236            Self::U32(..) => U32::<A>::type_name(),
237            Self::U64(..) => U64::<A>::type_name(),
238            Self::U128(..) => U128::<A>::type_name(),
239            Self::Scalar(..) => Scalar::<A>::type_name(),
240            Self::Signature(..) => Signature::<A>::type_name(),
241            Self::String(..) => StringType::<A>::type_name(),
242        }
243    }
244}
245
246impl<A: Aleo> Debug for Literal<A> {
247    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
248        Display::fmt(self, f)
249    }
250}
251
252impl<A: Aleo> Display for Literal<A> {
253    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
254        match self {
255            Self::Address(literal) => Display::fmt(literal, f),
256            Self::Boolean(literal) => Display::fmt(literal, f),
257            Self::Field(literal) => Display::fmt(literal, f),
258            Self::Group(literal) => Display::fmt(literal, f),
259            Self::I8(literal) => Display::fmt(literal, f),
260            Self::I16(literal) => Display::fmt(literal, f),
261            Self::I32(literal) => Display::fmt(literal, f),
262            Self::I64(literal) => Display::fmt(literal, f),
263            Self::I128(literal) => Display::fmt(literal, f),
264            Self::U8(literal) => Display::fmt(literal, f),
265            Self::U16(literal) => Display::fmt(literal, f),
266            Self::U32(literal) => Display::fmt(literal, f),
267            Self::U64(literal) => Display::fmt(literal, f),
268            Self::U128(literal) => Display::fmt(literal, f),
269            Self::Scalar(literal) => Display::fmt(literal, f),
270            Self::Signature(literal) => Display::fmt(literal, f),
271            Self::String(literal) => Display::fmt(literal, f),
272        }
273    }
274}