cairo_lang_starknet/inline_macros/
selector.rs

1use 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_starknet_classes::keccak::starknet_keccak;
7use cairo_lang_syntax::node::db::SyntaxGroup;
8use cairo_lang_syntax::node::{TypedStablePtr, TypedSyntaxNode, ast};
9
10/// Macro for expanding a selector to a string literal.
11#[derive(Debug, Default)]
12pub struct SelectorMacro;
13impl NamedPlugin for SelectorMacro {
14    const NAME: &'static str = "selector";
15}
16impl InlineMacroExprPlugin for SelectorMacro {
17    fn generate_code(
18        &self,
19        db: &dyn SyntaxGroup,
20        syntax: &ast::ExprInlineMacro,
21        _metadata: &MacroPluginMetadata<'_>,
22    ) -> InlinePluginResult {
23        let arg = extract_macro_single_unnamed_arg!(
24            db,
25            syntax,
26            ast::WrappedArgList::ParenthesizedArgList(_)
27        );
28
29        let ast::Expr::String(input_string) = arg else {
30            let diagnostics = vec![PluginDiagnostic::error(
31                syntax.stable_ptr().untyped(),
32                format!("`{}` macro argument must be a string", SelectorMacro::NAME),
33            )];
34            return InlinePluginResult { code: None, diagnostics };
35        };
36        let selector_string = input_string.string_value(db).unwrap();
37
38        let selector = starknet_keccak(selector_string.as_bytes());
39        InlinePluginResult {
40            code: Some(PluginGeneratedFile {
41                name: "selector_inline_macro".into(),
42                content: format!("0x{}", selector.to_str_radix(16)),
43                code_mappings: vec![],
44                aux_data: None,
45                diagnostics_note: Default::default(),
46            }),
47            diagnostics: vec![],
48        }
49    }
50}