typhoon_cpi_generator_macro/
lib.rs1use {
2 proc_macro::{Span, TokenStream},
3 std::{fs::read_to_string, path::PathBuf},
4 syn::{parse::Parse, parse_macro_input, LitStr},
5 typhoon_cpi_generator::{anchor::gen_cpi, idl::Idl},
6};
7
8#[proc_macro]
9pub fn anchor_cpi(input: TokenStream) -> TokenStream {
10 let idl_file = parse_macro_input!(input as IdlFile);
11 let idl: Idl = match serde_json::from_str(&idl_file.content) {
12 Ok(idl) => idl,
13 Err(err) => {
14 return syn::Error::new(
15 Span::call_site().into(),
16 format!("Failed to parse IDL: {err}"),
17 )
18 .to_compile_error()
19 .into();
20 }
21 };
22
23 gen_cpi(&idl).into()
24}
25struct IdlFile {
26 pub content: String,
27}
28
29impl Parse for IdlFile {
30 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
31 let path: LitStr = input.parse()?;
32 let path_str = path.value();
33
34 let var = std::env::var("CARGO_MANIFEST_DIR")
35 .map_err(|err| syn::Error::new(input.span(), err.to_string()))?;
36 let mut so_path = PathBuf::from(var);
37 so_path.push(path_str);
38
39 let content = read_to_string(so_path)
40 .map_err(|_| syn::Error::new(path.span(), "Unable to read file"))?;
41
42 Ok(IdlFile { content })
43 }
44}