use syn::{
parse::{
Parse,
ParseStream
},
punctuated::Punctuated,
custom_keyword,
DeriveInput,
Attribute,
Token,
};
pub (crate) mod enum_ty;
pub (crate) mod variant;
mod keywords {
use super::custom_keyword;
custom_keyword!(scope);
custom_keyword!(with_log);
custom_keyword!(default_level);
custom_keyword!(default_facade);
custom_keyword!(default_options);
custom_keyword!(ignore);
custom_keyword!(level);
custom_keyword!(facade);
custom_keyword!(name);
}
use std::fmt::Debug;
trait ParseStreamExt {
fn parse_keyword<K, F>(&self) -> syn::Result<(K, F)> where K: Parse + Debug, F: Parse + Debug;
}
impl ParseStreamExt for ParseStream<'_> {
#[inline]
fn parse_keyword<K,F>(&self) -> syn::Result<(K, F)> where K: Parse + Debug, F: Parse + Debug {
let kw = self.parse::<K>()?;
self.parse::<Token![=]>()?; let attr = self.parse::<F>()?;
Ok((kw, attr))
}
}
pub trait DeriveInputExt {
fn decode_meta<T: Parse>(&self, ident: &str) -> syn::Result<Vec<T>>;
}
impl DeriveInputExt for DeriveInput {
fn decode_meta<T: Parse>(&self, ident: &str) -> syn::Result<Vec<T>> {
decode_meta_inner(ident, &self.attrs)
}
}
impl DeriveInputExt for syn::Variant {
fn decode_meta<T: Parse>(&self, ident: &str) -> syn::Result<Vec<T>> {
decode_meta_inner(ident, &self.attrs)
}
}
pub trait DerivePropertiesExt<T> {
fn parse_properties(&self, ident: &str) -> syn::Result<T>;
}
#[inline(always)]
fn decode_meta_inner<'a, T: Parse>(ident: &str, it: impl IntoIterator<Item = &'a Attribute>)
-> syn::Result<Vec<T>> {
it.into_iter().filter(|a| a.path().is_ident(ident)).try_fold(
Vec::new(), |mut vec, attr| {
vec.extend(attr.parse_args_with(Punctuated::<T, Token![,]>::parse_terminated)?);
Ok(vec)
}
)
}