use syn::*;
use crate::utils::*;
pub(super) trait Attrs {
fn attrs(&self) -> &[Attribute];
fn any_attr<S: AsRef<str>>(&self, ident: S) -> bool {
any_attr(self.attrs(), ident.as_ref(), false)
}
fn any_empty_attr<S: AsRef<str>>(&self, ident: S) -> bool {
any_attr(self.attrs(), ident.as_ref(), true)
}
}
fn any_attr(attrs: &[Attribute], ident: &str, require_empty: bool) -> bool {
attrs
.iter()
.any(|attr| attr.path.is_ident(ident) && (!require_empty || attr.tts.is_empty()))
}
pub(super) trait AttrsMut: Attrs {
fn attrs_mut(&mut self) -> &mut Vec<Attribute>;
fn find_remove_attr<S: AsRef<str>>(&mut self, ident: S) -> Option<Attribute> {
find_remove_attr(self.attrs_mut(), ident.as_ref(), false)
}
fn find_remove_empty_attr<S: AsRef<str>>(&mut self, ident: S) -> bool {
find_remove_attr(self.attrs_mut(), ident.as_ref(), true).is_some()
}
}
fn find_remove_attr(
attrs: &mut Vec<Attribute>,
ident: &str,
require_empty: bool,
) -> Option<Attribute> {
attrs.find_remove(|attr| attr.path.is_ident(ident) && (!require_empty || attr.tts.is_empty()))
}
impl<'a, A: Attrs> Attrs for &'a A {
fn attrs(&self) -> &[Attribute] {
(**self).attrs()
}
}
impl<'a, A: Attrs> Attrs for &'a mut A {
fn attrs(&self) -> &[Attribute] {
(**self).attrs()
}
}
impl<'a, A: AttrsMut> AttrsMut for &'a mut A {
fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
(**self).attrs_mut()
}
}
impl Attrs for [Attribute] {
fn attrs(&self) -> &[Attribute] {
self
}
}
impl Attrs for Vec<Attribute> {
fn attrs(&self) -> &[Attribute] {
self
}
}
impl AttrsMut for Vec<Attribute> {
fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
self
}
}
impl Attrs for Local {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
}
impl AttrsMut for Local {
fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
&mut self.attrs
}
}
impl Attrs for Arm {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
}
impl AttrsMut for Arm {
fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
&mut self.attrs
}
}
macro_rules! attrs_impl {
($($Expr:ident($Self:ident)),*) => {
$(impl Attrs for $Self {
fn attrs(&self) -> &[Attribute] {
&self.attrs
}
}
impl AttrsMut for $Self {
fn attrs_mut(&mut self) -> &mut Vec<Attribute> {
&mut self.attrs
}
})*
impl Attrs for Expr {
fn attrs(&self) -> &[Attribute] {
match self {
$(Expr::$Expr(expr) => &expr.attrs,)*
Expr::Verbatim(_) => &[],
}
}
}
pub(super) fn attrs_mut<T, F: FnOnce(&mut Vec<Attribute>) -> T>(expr: &mut Expr, f: F) -> T {
match expr {
$(Expr::$Expr(expr) => f(&mut expr.attrs),)*
Expr::Verbatim(_) => f(&mut Vec::with_capacity(0)),
}
}
};
}
attrs_impl! {
Box(ExprBox),
InPlace(ExprInPlace),
Array(ExprArray),
Call(ExprCall),
MethodCall(ExprMethodCall),
Tuple(ExprTuple),
Binary(ExprBinary),
Unary(ExprUnary),
Lit(ExprLit),
Cast(ExprCast),
Type(ExprType),
Let(ExprLet),
If(ExprIf),
While(ExprWhile),
ForLoop(ExprForLoop),
Loop(ExprLoop),
Match(ExprMatch),
Closure(ExprClosure),
Unsafe(ExprUnsafe),
Block(ExprBlock),
Assign(ExprAssign),
AssignOp(ExprAssignOp),
Field(ExprField),
Index(ExprIndex),
Range(ExprRange),
Path(ExprPath),
Reference(ExprReference),
Break(ExprBreak),
Continue(ExprContinue),
Return(ExprReturn),
Macro(ExprMacro),
Struct(ExprStruct),
Repeat(ExprRepeat),
Paren(ExprParen),
Group(ExprGroup),
Try(ExprTry),
Async(ExprAsync),
TryBlock(ExprTryBlock),
Yield(ExprYield)
}