assert_type_match/
flags.rsuse syn::parse::{Parse, ParseStream};
use syn::spanned::Spanned;
use syn::token::Token;
use syn::{LitBool, Token};
pub(crate) type Flag = Option<LitBool>;
pub(crate) trait ParseFlag {
fn parse_flag<T: Parse + Spanned>(&self) -> syn::Result<Flag>;
}
impl<'a> ParseFlag for ParseStream<'a> {
fn parse_flag<T: Parse + Spanned>(&self) -> syn::Result<Flag> {
let keyword = self.parse::<T>()?;
if self.peek(Token![=]) {
self.parse::<Token![=]>()?;
Ok(Some(self.parse::<LitBool>()?))
} else {
Ok(Some(LitBool::new(true, keyword.span())))
}
}
}
pub(crate) fn flag_to_bool(flag: &Flag) -> bool {
flag.as_ref().map(LitBool::value).unwrap_or_default()
}
pub(crate) fn merge_flags<T: Token>(base: Flag, other: Flag) -> syn::Result<Flag> {
match (base, other) {
(Some(a), Some(b)) if a.value == b.value => Ok(Some(a)),
(Some(a), None) => Ok(Some(a)),
(None, Some(b)) => Ok(Some(b)),
(None, None) => Ok(None),
(Some(_), Some(b)) => Err(syn::Error::new_spanned(
b,
format_args!("conflicting `{}` arguments", T::display()),
)),
}
}