alacritty_config_derive/
lib.rs1#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use)]
2#![cfg_attr(clippy, deny(warnings))]
3
4use proc_macro::TokenStream;
5use proc_macro2::TokenStream as TokenStream2;
6use quote::quote;
7use syn::parse::{self, Parse, ParseStream};
8use syn::punctuated::Punctuated;
9use syn::{GenericParam, Ident, LitStr, Token, TypeParam};
10
11mod config_deserialize;
12mod serde_replace;
13
14pub(crate) const MULTIPLE_FLATTEN_ERROR: &str =
16 "At most one instance of #[config(flatten)] is supported";
17
18#[proc_macro_derive(ConfigDeserialize, attributes(config))]
19pub fn derive_config_deserialize(input: TokenStream) -> TokenStream {
20 config_deserialize::derive(input)
21}
22
23#[proc_macro_derive(SerdeReplace)]
24pub fn derive_serde_replace(input: TokenStream) -> TokenStream {
25 serde_replace::derive(input)
26}
27
28#[derive(Default)]
30struct GenericsStreams {
31 unconstrained: TokenStream2,
32 constrained: TokenStream2,
33 phantoms: TokenStream2,
34}
35
36pub(crate) fn generics_streams<T>(params: &Punctuated<GenericParam, T>) -> GenericsStreams {
43 let mut generics = GenericsStreams::default();
44
45 for generic in params {
46 if let GenericParam::Type(TypeParam { ident, .. }) = generic {
48 generics.unconstrained.extend(quote!( #ident , ));
49 generics.constrained.extend(quote! {
50 #ident : Default + serde::Deserialize<'de> + alacritty_config::SerdeReplace,
51 });
52 generics.phantoms.extend(quote! {
53 #ident : std::marker::PhantomData < #ident >,
54 });
55 }
56 }
57
58 generics
59}
60
61pub(crate) struct Attr {
63 ident: String,
64 param: Option<LitStr>,
65}
66
67impl Parse for Attr {
68 fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
69 let ident = input.parse::<Ident>()?.to_string();
70 let param = input.parse::<Token![=]>().and_then(|_| input.parse()).ok();
71 Ok(Self { ident, param })
72 }
73}