cairo_lang_starknet/inline_macros/
selector.rs1use cairo_lang_defs::extract_macro_single_unnamed_arg;
2use cairo_lang_defs::plugin::{
3 InlineMacroExprPlugin, InlinePluginResult, MacroPluginMetadata, NamedPlugin, PluginDiagnostic,
4 PluginGeneratedFile,
5};
6use cairo_lang_defs::plugin_utils::{PluginResultTrait, not_legacy_macro_diagnostic};
7use cairo_lang_parser::macro_helpers::AsLegacyInlineMacro;
8use cairo_lang_starknet_classes::keccak::starknet_keccak;
9use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode, ast};
10use salsa::Database;
11
12#[derive(Debug, Default)]
14pub struct SelectorMacro;
15impl NamedPlugin for SelectorMacro {
16 const NAME: &'static str = "selector";
17}
18impl InlineMacroExprPlugin for SelectorMacro {
19 fn generate_code<'db>(
20 &self,
21 db: &'db dyn Database,
22 syntax: &ast::ExprInlineMacro<'db>,
23 _metadata: &MacroPluginMetadata<'_>,
24 ) -> InlinePluginResult<'db> {
25 let Some(legacy_inline_macro) = syntax.as_legacy_inline_macro(db) else {
26 return InlinePluginResult::diagnostic_only(not_legacy_macro_diagnostic(
27 syntax.as_syntax_node().stable_ptr(db),
28 ));
29 };
30 let arg = extract_macro_single_unnamed_arg!(
31 db,
32 &legacy_inline_macro,
33 ast::WrappedArgList::ParenthesizedArgList(_),
34 syntax.stable_ptr(db)
35 );
36
37 let ast::Expr::String(input_string) = arg else {
38 let diagnostics = vec![PluginDiagnostic::error(
39 syntax.stable_ptr(db).untyped(),
40 format!("`{}` macro argument must be a string", SelectorMacro::NAME),
41 )];
42 return InlinePluginResult { code: None, diagnostics };
43 };
44 let selector_string = input_string.string_value(db).unwrap();
45
46 let selector = starknet_keccak(selector_string.as_bytes());
47 InlinePluginResult {
48 code: Some(PluginGeneratedFile {
49 name: "selector_inline_macro".into(),
50 content: format!("0x{}", selector.to_str_radix(16)),
51 code_mappings: vec![],
52 aux_data: None,
53 diagnostics_note: Default::default(),
54 is_unhygienic: false,
55 }),
56 diagnostics: vec![],
57 }
58 }
59}