1use serde::{Deserialize, Serialize};
2
3#[cfg(feature = "test_utils")]
4use arbitrary::{self, Arbitrary};
5
6const OUTPUT_BUILTIN_NAME: &str = "output";
8const HASH_BUILTIN_NAME: &str = "pedersen";
9const RANGE_CHECK_BUILTIN_NAME: &str = "range_check";
10const RANGE_CHECK_96_BUILTIN_NAME: &str = "range_check96";
11const SIGNATURE_BUILTIN_NAME: &str = "ecdsa";
12const BITWISE_BUILTIN_NAME: &str = "bitwise";
13const EC_OP_BUILTIN_NAME: &str = "ec_op";
14const KECCAK_BUILTIN_NAME: &str = "keccak";
15const POSEIDON_BUILTIN_NAME: &str = "poseidon";
16const SEGMENT_ARENA_BUILTIN_NAME: &str = "segment_arena";
17const ADD_MOD_BUILTIN_NAME: &str = "add_mod";
18const MUL_MOD_BUILTIN_NAME: &str = "mul_mod";
19
20const OUTPUT_BUILTIN_NAME_WITH_SUFFIX: &str = "output_builtin";
21const HASH_BUILTIN_NAME_WITH_SUFFIX: &str = "pedersen_builtin";
22const RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX: &str = "range_check_builtin";
23const RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX: &str = "range_check96_builtin";
24const SIGNATURE_BUILTIN_NAME_WITH_SUFFIX: &str = "ecdsa_builtin";
25const BITWISE_BUILTIN_NAME_WITH_SUFFIX: &str = "bitwise_builtin";
26const EC_OP_BUILTIN_NAME_WITH_SUFFIX: &str = "ec_op_builtin";
27const KECCAK_BUILTIN_NAME_WITH_SUFFIX: &str = "keccak_builtin";
28const POSEIDON_BUILTIN_NAME_WITH_SUFFIX: &str = "poseidon_builtin";
29const SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX: &str = "segment_arena_builtin";
30const ADD_MOD_BUILTIN_NAME_WITH_SUFFIX: &str = "add_mod_builtin";
31const MUL_MOD_BUILTIN_NAME_WITH_SUFFIX: &str = "mul_mod_builtin";
32
33#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
35#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Eq, Hash)]
36#[allow(non_camel_case_types)]
37pub enum BuiltinName {
38 output,
39 range_check,
40 pedersen,
41 ecdsa,
42 keccak,
43 bitwise,
44 ec_op,
45 poseidon,
46 segment_arena,
47 range_check96,
48 add_mod,
49 mul_mod,
50}
51
52impl BuiltinName {
53 pub fn to_str_with_suffix(self) -> &'static str {
65 match self {
66 BuiltinName::output => OUTPUT_BUILTIN_NAME_WITH_SUFFIX,
67 BuiltinName::range_check => RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX,
68 BuiltinName::pedersen => HASH_BUILTIN_NAME_WITH_SUFFIX,
69 BuiltinName::ecdsa => SIGNATURE_BUILTIN_NAME_WITH_SUFFIX,
70 BuiltinName::keccak => KECCAK_BUILTIN_NAME_WITH_SUFFIX,
71 BuiltinName::bitwise => BITWISE_BUILTIN_NAME_WITH_SUFFIX,
72 BuiltinName::ec_op => EC_OP_BUILTIN_NAME_WITH_SUFFIX,
73 BuiltinName::poseidon => POSEIDON_BUILTIN_NAME_WITH_SUFFIX,
74 BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX,
75 BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX,
76 BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME_WITH_SUFFIX,
77 BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME_WITH_SUFFIX,
78 }
79 }
80
81 pub fn to_str(self) -> &'static str {
93 match self {
94 BuiltinName::output => OUTPUT_BUILTIN_NAME,
95 BuiltinName::range_check => RANGE_CHECK_BUILTIN_NAME,
96 BuiltinName::pedersen => HASH_BUILTIN_NAME,
97 BuiltinName::ecdsa => SIGNATURE_BUILTIN_NAME,
98 BuiltinName::keccak => KECCAK_BUILTIN_NAME,
99 BuiltinName::bitwise => BITWISE_BUILTIN_NAME,
100 BuiltinName::ec_op => EC_OP_BUILTIN_NAME,
101 BuiltinName::poseidon => POSEIDON_BUILTIN_NAME,
102 BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME,
103 BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME,
104 BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME,
105 BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME,
106 }
107 }
108
109 pub fn from_str_with_suffix(suffixed_str: &str) -> Option<Self> {
122 match suffixed_str {
123 OUTPUT_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::output),
124 RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::range_check),
125 HASH_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::pedersen),
126 SIGNATURE_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::ecdsa),
127 KECCAK_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::keccak),
128 BITWISE_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::bitwise),
129 EC_OP_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::ec_op),
130 POSEIDON_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::poseidon),
131 SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::segment_arena),
132 RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::range_check96),
133 ADD_MOD_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::add_mod),
134 MUL_MOD_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::mul_mod),
135 _ => None,
136 }
137 }
138
139 #[allow(clippy::should_implement_trait)]
141 pub fn from_str(str: &str) -> Option<Self> {
154 match str {
155 OUTPUT_BUILTIN_NAME => Some(BuiltinName::output),
156 RANGE_CHECK_BUILTIN_NAME => Some(BuiltinName::range_check),
157 HASH_BUILTIN_NAME => Some(BuiltinName::pedersen),
158 SIGNATURE_BUILTIN_NAME => Some(BuiltinName::ecdsa),
159 KECCAK_BUILTIN_NAME => Some(BuiltinName::keccak),
160 BITWISE_BUILTIN_NAME => Some(BuiltinName::bitwise),
161 EC_OP_BUILTIN_NAME => Some(BuiltinName::ec_op),
162 POSEIDON_BUILTIN_NAME => Some(BuiltinName::poseidon),
163 SEGMENT_ARENA_BUILTIN_NAME => Some(BuiltinName::segment_arena),
164 RANGE_CHECK_96_BUILTIN_NAME => Some(BuiltinName::range_check96),
165 ADD_MOD_BUILTIN_NAME => Some(BuiltinName::add_mod),
166 MUL_MOD_BUILTIN_NAME => Some(BuiltinName::mul_mod),
167 _ => None,
168 }
169 }
170}
171
172impl core::fmt::Display for BuiltinName {
174 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
175 self.to_str_with_suffix().fmt(f)
176 }
177}
178
179pub(crate) mod serde_generic_map_impl {
181 use super::BuiltinName;
182 use crate::stdlib::{collections::HashMap, string::String};
183 use serde::{de::Error, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
184
185 pub fn serialize<S, V>(
186 values: &HashMap<BuiltinName, V>,
187 serializer: S,
188 ) -> Result<S::Ok, S::Error>
189 where
190 S: Serializer,
191 V: Serialize,
192 {
193 let mut map_serializer = serializer.serialize_map(Some(values.len()))?;
194 for (key, val) in values {
195 map_serializer.serialize_entry(key.to_str_with_suffix(), val)?
196 }
197 map_serializer.end()
198 }
199
200 pub fn deserialize<'de, D: Deserializer<'de>, V: Deserialize<'de>>(
201 d: D,
202 ) -> Result<HashMap<BuiltinName, V>, D::Error> {
203 let map = HashMap::<String, V>::deserialize(d)?;
205 map.into_iter()
207 .map(|(k, v)| BuiltinName::from_str_with_suffix(&k).map(|k| (k, v)))
208 .collect::<Option<HashMap<_, _>>>()
209 .ok_or(D::Error::custom("Invalid builtin name"))
210 }
211}