anchor_syn/parser/
spl_interface.rs1#[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 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]; } else if instruction == "execute" {
57 return [105, 37, 101, 197, 75, 251, 102, 26]; } else {
59 panic!("Unsupported instruction: {}", instruction);
60 }
61 }
62 panic!("Unsupported interface: {}", interface);
63}