polymesh_api_codegen_macro/
lib.rs1use 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 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}