macro_rules! parse_any {
($vis:vis enum $enum:ident {
$(
$variant:ident($ty:ty)
),*
$(,)?
}) => {
$vis enum $enum {
$(
$variant($ty)
),*
}
impl ::syn::parse::Parse for $enum {
fn parse(input: ::syn::parse::ParseStream<'_>) -> ::syn::Result<Self> {
$(if <<$ty as $crate::parser::KeywordToken>::Token as ::syn::token::Token>::peek(input.cursor()) {
input.parse().map(Self::$variant)
} else)* {
let mut error = String::from("expected one of: ");
$(
error.push_str(<$ty as $crate::parser::KeywordToken>::display());
error.push_str(", ");
)*
error.truncate(error.len() - 2);
Err(input.error(error))
}
}
}
};
}
macro_rules! attr_struct {
(
@$mode:ident $mod:ident
#[from($attr_ty:ident)]
$(#[$meta:meta])*
$vis:vis struct $ident:ident {
$(
$(#[cfg($cfg_ident:ident)])?
$(#[from($($field_attr_id:ident),+)])?
$field_vis:vis $field:ident : $field_ty:ty
),+ $(,)?
}
) => {
$(#[$meta])*
$vis struct $ident {
$(
$(
#[cfg($cfg_ident)]
)?
$field_vis $field: $field_ty,
)+
pub(crate) keyword_spans: Vec<proc_macro2::Span>,
}
impl $crate::parser::$mode::FromAttrs<$attr_ty> for $ident {
fn try_set_attr(&mut self, attr: $attr_ty) -> ::syn::Result<()> {
use crate::parser::KeywordToken;
match attr {
$($(
$($attr_ty::$field_attr_id(value) => {
self.keyword_spans.push(value.keyword_span());
value.try_set(&mut self.$field)
},)+
)?)+
}
}
}
mod $mod {
#[allow(unused_imports)]
use super::*;
use $crate::parser::$mode::attrs;
parse_any! {
$vis enum $attr_ty {
$($(
$($field_attr_id(attrs::$field_attr_id),)+
)?)+
}
}
}
$vis use $mod::$attr_ty;
}
}