polymesh_api_codegen_macro/
lib.rs

1use std::env;
2use std::fs::File;
3use std::io::Read;
4use std::path::Path;
5
6use proc_macro::TokenStream;
7use proc_macro_error::{abort_call_site, proc_macro_error};
8
9use darling::{FromMeta, ToTokens};
10use syn::parse_macro_input;
11
12#[derive(Clone, FromMeta)]
13struct CodegenArgs {
14  metadata_file: Option<String>,
15  metadata_url: Option<String>,
16}
17
18#[proc_macro_attribute]
19#[proc_macro_error]
20pub fn codegen_api(args: TokenStream, input: TokenStream) -> TokenStream {
21  let args = parse_macro_input!(args as syn::AttributeArgs);
22  let item = parse_macro_input!(input as syn::ItemMod);
23  let args = CodegenArgs::from_list(&args).unwrap_or_else(|e| abort_call_site!(e));
24
25  let buf = match args {
26    CodegenArgs {
27      metadata_file: Some(filename),
28      metadata_url: None,
29    } => {
30      let root = env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".into());
31      let filename = Path::new(&root).join(filename);
32      let mut file = File::open(filename).unwrap_or_else(|e| abort_call_site!(e));
33      let mut buf = Vec::new();
34      file
35        .read_to_end(&mut buf)
36        .unwrap_or_else(|e| abort_call_site!(e));
37      buf
38    }
39    #[cfg(feature = "download_metadata")]
40    CodegenArgs {
41      metadata_file: None,
42      metadata_url: Some(url),
43    } => {
44      let url = if &url == "POLYMESH_NODE_URL" {
45        std::env::var("POLYMESH_NODE_URL").unwrap_or_else(|_| "ws://localhost:9944".into())
46      } else {
47        url
48      };
49      let rt = tokio::runtime::Runtime::new().unwrap();
50      rt.block_on(async {
51        use codec::Encode;
52        use polymesh_api_client::*;
53
54        let client = Client::new(&url)
55          .await
56          .unwrap_or_else(|e| abort_call_site!(e));
57
58        // Get current Metadata.
59        let metadata = client
60          .get_block_metadata(None)
61          .await
62          .unwrap_or_else(|e| abort_call_site!(e))
63          .expect("Chain metadata");
64
65        metadata.encode()
66      })
67    }
68    #[cfg(not(feature = "download_metadata"))]
69    CodegenArgs {
70      metadata_file: None,
71      metadata_url: Some(_),
72    } => {
73      panic!("Support `metadata_url` disabled, add feature `download_metadata`.");
74    }
75    _ => {
76      panic!("Must provide either `metadata_file` or `metadata_url`, but not both.");
77    }
78  };
79
80  match polymesh_api_codegen::macro_codegen(&buf, item.ident.into_token_stream().into()) {
81    Ok(out) => out.into(),
82    Err(err) => abort_call_site!(err),
83  }
84}