Skip to main content

snarkvm_circuit_program/data/literal/
mod.rs

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