anchor_syn/parser/
spl_interface.rs

1#[cfg(feature = "interface-instructions")]
2use syn::{Meta, NestedMeta, Path};
3
4#[cfg(not(feature = "interface-instructions"))]
5pub fn parse(_attrs: &[syn::Attribute]) -> Option<[u8; 8]> {
6    None
7}
8
9#[cfg(feature = "interface-instructions")]
10pub fn parse(attrs: &[syn::Attribute]) -> Option<[u8; 8]> {
11    let interfaces: Vec<[u8; 8]> = attrs
12        .iter()
13        .filter_map(|attr| {
14            if attr.path.is_ident("interface") {
15                if let Ok(Meta::List(meta_list)) = attr.parse_meta() {
16                    if let Some(NestedMeta::Meta(Meta::Path(path))) = meta_list.nested.first() {
17                        return Some(parse_interface_instruction(path));
18                    }
19                }
20                panic!(
21                    "Failed to parse interface instruction:\n{}",
22                    quote::quote!(#attr)
23                );
24            }
25            None
26        })
27        .collect();
28    if interfaces.len() > 1 {
29        panic!("An instruction can only implement one interface instruction");
30    } else if interfaces.is_empty() {
31        None
32    } else {
33        Some(interfaces[0])
34    }
35}
36
37#[cfg(feature = "interface-instructions")]
38fn parse_interface_instruction(path: &Path) -> [u8; 8] {
39    if path.segments.len() != 2 {
40        // All interface instruction args are expected to be in the form
41        // <interface>::<instruction>
42        panic!(
43            "Invalid interface instruction: {}",
44            path.segments
45                .iter()
46                .map(|segment| segment.ident.to_string())
47                .collect::<Vec<String>>()
48                .join("::")
49        );
50    }
51    let interface = path.segments[0].ident.to_string();
52    if interface == "spl_transfer_hook_interface" {
53        let instruction = path.segments[1].ident.to_string();
54        if instruction == "initialize_extra_account_meta_list" {
55            return [43, 34, 13, 49, 167, 88, 235, 235]; // `InitializeExtraAccountMetaList`
56        } else if instruction == "execute" {
57            return [105, 37, 101, 197, 75, 251, 102, 26]; // `Execute`
58        } else {
59            panic!("Unsupported instruction: {}", instruction);
60        }
61    }
62    panic!("Unsupported interface: {}", interface);
63}