crud_api_derive/
lib.rs

1//! # Api Derive
2//!
3//! Derive implementation for `Api`.
4//!
5//! See [`crud-api`](../crud-api) crate.
6
7mod api;
8mod config;
9mod gen_clap_declarations;
10mod gen_clap_matches;
11mod gen_init;
12mod input;
13
14use api::api;
15use crud_api_endpoint::ApiRun;
16use darling::FromDeriveInput;
17use gen_clap_declarations::subcommands;
18use gen_clap_matches::argmatches;
19use gen_init::{init_clap, settings};
20use input::api_input_derive;
21use proc_macro::TokenStream;
22use proc_macro_error::proc_macro_error;
23use quote::quote;
24use syn::{parse, DeriveInput};
25
26/// Attribute used by `ApiRun`. [struct@ApiRun]
27#[proc_macro_derive(ApiRun, attributes(api))]
28#[proc_macro_error]
29#[rustfmt::skip::macros(quote)]
30#[allow(clippy::let_and_return)]
31pub fn api_run_macro_derive(input: TokenStream) -> TokenStream {
32  let ast: DeriveInput = parse(input).unwrap();
33  let api = ApiRun::from_derive_input(&ast).unwrap();
34  let name = &api.ident;
35
36  let settings = settings(&api);
37  let init_clap = init_clap(&api);
38  let subcommands = subcommands();
39  let base_url = &api.infos.base_url;
40  let matches = argmatches();
41
42  let eh: Vec<proc_macro2::TokenStream> = api
43    .extra_header
44    .iter()
45    .map(|h| {
46      let key = &h.key;
47      let value = &h.value;
48      quote!(crud_api::http::Header{key:#key, value:#value})
49    })
50    .collect();
51
52  let out = quote! {
53      impl #name {
54	 async fn run() -> miette::Result<()> {
55	     use miette::{IntoDiagnostic, WrapErr};
56	     pretty_env_logger::init();
57	     let mut auth = Auth::default();
58	     let extra_headers: Vec<crud_api::http::Header> = vec![#(#eh),*];
59	     #settings
60	     #init_clap
61	     commands = auth.clap_auth(commands);
62	     #subcommands
63
64	     let matches = crud_api::cli::get_matches(&commands)?;
65	     let base_url = if let Ok(url) =
66		 crud_api::settings::get_settings(&settings, &matches, "base_url") {
67		     url
68	     } else {
69		 #base_url.to_string()
70	     };
71	     auth.clap_matches(&matches,&mut commands,&settings);
72	     match matches.subcommand() {
73		  #matches
74		  Some(("completion", completions)) =>
75		      crud_api::completions::generate_completions(completions, &mut commands),
76		  Some((_,_))=> commands.print_help().into_diagnostic()?,
77		  None => commands.print_help().into_diagnostic()?,
78	      }
79	      Ok(())
80	  }
81      }
82  }
83  .into();
84  #[cfg(feature = "dump-derives")]
85  println!("{}", out);
86  out
87}
88
89#[proc_macro_derive(Api, attributes(api))]
90#[proc_macro_error]
91#[allow(clippy::let_and_return)]
92pub fn api_macro_derive(input: TokenStream) -> TokenStream {
93  let ast: DeriveInput = parse(input).unwrap();
94  let out = api(&ast);
95  #[cfg(feature = "dump-derives")]
96  println!("{}", out);
97  out
98}
99
100#[proc_macro_derive(ApiInput, attributes(api))]
101#[proc_macro_error]
102#[allow(clippy::let_and_return)]
103pub fn api_input_macro_derive(input: TokenStream) -> TokenStream {
104  let ast: DeriveInput = parse(input).unwrap();
105  let out = api_input_derive(&ast).into();
106  #[cfg(feature = "dump-derives")]
107  println!("{}", out);
108  out
109}