1use crate::{ArrayType, CompositeType, FutureType, Identifier, IntegerType, MappingType, TupleType, common};
18
19use itertools::Itertools;
20use leo_span::Symbol;
21use serde::{Deserialize, Serialize};
22use snarkvm::prelude::{
23 Network,
24 PlaintextType,
25 PlaintextType::{Array, Literal, Struct},
26};
27use std::fmt;
28
29#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
31pub enum Type {
32 Address,
34 Array(ArrayType),
36 Boolean,
38 Composite(CompositeType),
40 Field,
42 Future(FutureType),
44 Group,
46 Identifier(Identifier),
48 Integer(IntegerType),
50 Mapping(MappingType),
52 Scalar,
54 Signature,
56 String,
58 Tuple(TupleType),
60 Numeric,
62 Unit,
64 #[default]
67 Err,
68}
69
70impl Type {
71 pub fn eq_flat_relaxed(&self, other: &Self) -> bool {
78 match (self, other) {
79 (Type::Address, Type::Address)
80 | (Type::Boolean, Type::Boolean)
81 | (Type::Field, Type::Field)
82 | (Type::Group, Type::Group)
83 | (Type::Scalar, Type::Scalar)
84 | (Type::Signature, Type::Signature)
85 | (Type::String, Type::String)
86 | (Type::Unit, Type::Unit) => true,
87 (Type::Array(left), Type::Array(right)) => {
88 left.element_type().eq_flat_relaxed(right.element_type())
91 && left.length.as_u32().is_some()
92 && right.length.as_u32().is_some()
93 && left.length.as_u32() == right.length.as_u32()
94 }
95 (Type::Identifier(left), Type::Identifier(right)) => left.matches(right),
96 (Type::Integer(left), Type::Integer(right)) => left.eq(right),
97 (Type::Mapping(left), Type::Mapping(right)) => {
98 left.key.eq_flat_relaxed(&right.key) && left.value.eq_flat_relaxed(&right.value)
99 }
100 (Type::Tuple(left), Type::Tuple(right)) if left.length() == right.length() => left
101 .elements()
102 .iter()
103 .zip_eq(right.elements().iter())
104 .all(|(left_type, right_type)| left_type.eq_flat_relaxed(right_type)),
105 (Type::Composite(left), Type::Composite(right)) => left.id.name == right.id.name,
106 (Type::Future(left), Type::Future(right)) if !left.is_explicit || !right.is_explicit => true,
108 (Type::Future(left), Type::Future(right)) if left.inputs.len() == right.inputs.len() => left
109 .inputs()
110 .iter()
111 .zip_eq(right.inputs().iter())
112 .all(|(left_type, right_type)| left_type.eq_flat_relaxed(right_type)),
113 _ => false,
114 }
115 }
116
117 pub fn from_snarkvm<N: Network>(t: &PlaintextType<N>, program: Option<Symbol>) -> Self {
118 match t {
119 Literal(lit) => match lit {
120 snarkvm::prelude::LiteralType::Address => Type::Address,
121 snarkvm::prelude::LiteralType::Boolean => Type::Boolean,
122 snarkvm::prelude::LiteralType::Field => Type::Field,
123 snarkvm::prelude::LiteralType::Group => Type::Group,
124 snarkvm::prelude::LiteralType::U8 => Type::Integer(IntegerType::U8),
125 snarkvm::prelude::LiteralType::U16 => Type::Integer(IntegerType::U16),
126 snarkvm::prelude::LiteralType::U32 => Type::Integer(IntegerType::U32),
127 snarkvm::prelude::LiteralType::U64 => Type::Integer(IntegerType::U64),
128 snarkvm::prelude::LiteralType::U128 => Type::Integer(IntegerType::U128),
129 snarkvm::prelude::LiteralType::I8 => Type::Integer(IntegerType::I8),
130 snarkvm::prelude::LiteralType::I16 => Type::Integer(IntegerType::I16),
131 snarkvm::prelude::LiteralType::I32 => Type::Integer(IntegerType::I32),
132 snarkvm::prelude::LiteralType::I64 => Type::Integer(IntegerType::I64),
133 snarkvm::prelude::LiteralType::I128 => Type::Integer(IntegerType::I128),
134 snarkvm::prelude::LiteralType::Scalar => Type::Scalar,
135 snarkvm::prelude::LiteralType::Signature => Type::Signature,
136 snarkvm::prelude::LiteralType::String => Type::String,
137 },
138 Struct(s) => Type::Composite(CompositeType { id: common::Identifier::from(s), program }),
139 Array(array) => Type::Array(ArrayType::from_snarkvm(array, program)),
140 }
141 }
142}
143
144impl fmt::Display for Type {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 match *self {
147 Type::Address => write!(f, "address"),
148 Type::Array(ref array_type) => write!(f, "{array_type}"),
149 Type::Boolean => write!(f, "bool"),
150 Type::Field => write!(f, "field"),
151 Type::Future(ref future_type) => write!(f, "{future_type}"),
152 Type::Group => write!(f, "group"),
153 Type::Identifier(ref variable) => write!(f, "{variable}"),
154 Type::Integer(ref integer_type) => write!(f, "{integer_type}"),
155 Type::Mapping(ref mapping_type) => write!(f, "{mapping_type}"),
156 Type::Scalar => write!(f, "scalar"),
157 Type::Signature => write!(f, "signature"),
158 Type::String => write!(f, "string"),
159 Type::Composite(ref struct_type) => write!(f, "{struct_type}"),
160 Type::Tuple(ref tuple) => write!(f, "{tuple}"),
161 Type::Numeric => write!(f, "numeric"),
162 Type::Unit => write!(f, "()"),
163 Type::Err => write!(f, "error"),
164 }
165 }
166}