added final macro to auto implement cli from api types
This commit is contained in:
56
src/lib.rs
56
src/lib.rs
@ -248,3 +248,59 @@ pub fn alpaca_cli(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn api_dispatch(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(item as syn::ItemEnum);
|
||||
let enum_ident = &input.ident;
|
||||
|
||||
// Parse attribute input: input = "MyQuery"
|
||||
let meta_args = attr.to_string();
|
||||
let input_type: syn::Ident = {
|
||||
let cleaned = meta_args.trim().replace("input", "").replace('=', "").replace('"', "").trim().to_string();
|
||||
syn::Ident::new(&cleaned, proc_macro2::Span::call_site())
|
||||
};
|
||||
|
||||
let expanded = quote! {
|
||||
#input
|
||||
|
||||
impl ApiDispatch for #enum_ident {
|
||||
fn send_all(
|
||||
&self,
|
||||
client: &awc::Client,
|
||||
keys: &std::collections::HashMap<String, crate::Keys>,
|
||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), Box<dyn std::error::Error>>> + Send>> {
|
||||
Box::pin(async move {
|
||||
match self {
|
||||
#enum_ident::Single { query } => {
|
||||
let parsed: #input_type = serde_json::from_str(query)?;
|
||||
parsed.send(client, keys).await?;
|
||||
}
|
||||
#enum_ident::Bulk { input } => {
|
||||
let json = if let Some(raw) = input {
|
||||
if std::path::Path::new(&raw).exists() {
|
||||
std::fs::read_to_string(raw)?
|
||||
} else {
|
||||
raw.clone()
|
||||
}
|
||||
} else {
|
||||
use std::io::Read;
|
||||
let mut buf = String::new();
|
||||
std::io::stdin().read_to_string(&mut buf)?;
|
||||
buf
|
||||
};
|
||||
|
||||
let items: Vec<#input_type> = serde_json::from_str(&json)?;
|
||||
for item in items {
|
||||
item.send(client, keys).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
Reference in New Issue
Block a user