@@ -18,6 +18,7 @@ use starknet_api::transaction::{
1818 MessageToL1 as StarknetAPIMessageToL1 ,
1919} ;
2020use starknet_types_core:: felt:: Felt ;
21+ use strum:: { AsRefStr , Display , EnumString } ;
2122
2223use crate :: blockifier_versioned_constants:: VersionedConstants ;
2324use crate :: execution:: contract_class:: TrackedResource ;
@@ -273,11 +274,18 @@ impl AddAssign<&ChargedResources> for ChargedResources {
273274}
274275
275276#[ cfg_attr( feature = "transaction_serde" , derive( serde:: Deserialize ) ) ]
276- #[ derive( Clone , Debug , Eq , Hash , PartialEq , Serialize , Ord , PartialOrd ) ]
277+ #[ derive(
278+ Clone , Debug , Eq , Hash , PartialEq , Serialize , Ord , PartialOrd , Display , EnumString , AsRefStr ,
279+ ) ]
280+ #[ strum( serialize_all = "snake_case" ) ]
277281pub enum OpcodeName {
278282 Blake ,
279283}
280284
285+ /// Error type for parsing [`CairoPrimitiveName`] from a string.
286+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
287+ pub struct ParseCairoPrimitiveNameError ;
288+
281289#[ cfg_attr( feature = "transaction_serde" , derive( serde:: Deserialize ) ) ]
282290#[ derive( Clone , Debug , Eq , Hash , PartialEq , Serialize , Ord , PartialOrd ) ]
283291// Serialize as an untagged enum to avoid a type prefix, for backward compatibility with
@@ -288,6 +296,36 @@ pub enum CairoPrimitiveName {
288296 Opcode ( OpcodeName ) ,
289297}
290298
299+ impl CairoPrimitiveName {
300+ pub fn to_str ( & self ) -> & str {
301+ match self {
302+ Self :: Builtin ( builtin) => builtin. to_str ( ) ,
303+ Self :: Opcode ( opcode) => opcode. as_ref ( ) ,
304+ }
305+ }
306+ }
307+
308+ impl std:: fmt:: Display for CairoPrimitiveName {
309+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
310+ match self {
311+ Self :: Builtin ( builtin) => write ! ( f, "{builtin}" ) ,
312+ Self :: Opcode ( opcode) => write ! ( f, "{opcode}" ) ,
313+ }
314+ }
315+ }
316+
317+ impl std:: str:: FromStr for CairoPrimitiveName {
318+ type Err = ParseCairoPrimitiveNameError ;
319+
320+ /// Tries to parse as a builtin first, then as an opcode.
321+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
322+ if let Some ( builtin) = BuiltinName :: from_str ( s) {
323+ return Ok ( Self :: Builtin ( builtin) ) ;
324+ }
325+ s. parse :: < OpcodeName > ( ) . map ( Self :: Opcode ) . map_err ( |_| ParseCairoPrimitiveNameError )
326+ }
327+ }
328+
291329impl From < BuiltinName > for CairoPrimitiveName {
292330 fn from ( builtin_name : BuiltinName ) -> Self {
293331 CairoPrimitiveName :: Builtin ( builtin_name)
0 commit comments