use crate::ast::prelude::*;
#[test]
#[cfg(not(miri))]
fn ast_parse() {
assert!(matches! {
rt::<ast::Visibility>("pub"),
ast::Visibility::Public(_)
});
assert!(matches! {
rt::<ast::Visibility>("pub (in a::b::c)"),
ast::Visibility::In(_)
});
assert!(matches! {
rt::<ast::Visibility>("pub(in crate::x::y::z)"),
ast::Visibility::In(_)
});
assert!(matches! {
rt::<ast::Visibility>("pub(super)"),
ast::Visibility::Super(_)
});
assert!(matches! {
rt::<ast::Visibility>("pub(crate)"),
ast::Visibility::Crate(_)
});
assert!(matches! {
rt::<ast::Visibility>("pub(self)"),
ast::Visibility::SelfValue(_)
});
}
#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, OptionSpanned)]
#[non_exhaustive]
pub enum Visibility {
Inherited,
Public(T![pub]),
Crate(VisibilityRestrict<T![crate]>),
Super(VisibilityRestrict<T![super]>),
SelfValue(VisibilityRestrict<T![self]>),
In(VisibilityRestrict<VisibilityIn>),
}
impl Visibility {
pub const fn is_inherited(&self) -> bool {
matches!(self, Visibility::Inherited)
}
pub const fn is_public(&self) -> bool {
matches!(self, Visibility::Public(..))
}
}
impl Default for Visibility {
fn default() -> Self {
Self::Inherited
}
}
impl Parse for Visibility {
fn parse(parser: &mut Parser<'_>) -> Result<Self> {
let pub_token = match parser.parse::<Option<T![pub]>>()? {
Some(pub_token) => pub_token,
None => return Ok(Self::Inherited),
};
let open = match parser.parse::<Option<ast::OpenParen>>()? {
Some(open) => open,
None => return Ok(Self::Public(pub_token)),
};
Ok(match parser.nth(0)? {
K![in] => Self::In(VisibilityRestrict {
pub_token,
open,
restriction: VisibilityIn {
in_token: parser.parse()?,
path: parser.parse()?,
},
close: parser.parse()?,
}),
K![super] => Self::Super(VisibilityRestrict {
pub_token,
open,
restriction: parser.parse()?,
close: parser.parse()?,
}),
K![self] => Self::SelfValue(VisibilityRestrict {
pub_token,
open,
restriction: parser.parse()?,
close: parser.parse()?,
}),
_ => Self::Crate(VisibilityRestrict {
pub_token,
open,
restriction: parser.parse()?,
close: parser.parse()?,
}),
})
}
}
#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
#[non_exhaustive]
pub struct VisibilityIn {
pub in_token: T![in],
pub path: ast::Path,
}
#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
#[non_exhaustive]
#[try_clone(bound = {T: TryClone})]
pub struct VisibilityRestrict<T> {
pub pub_token: ast::generated::Pub,
pub open: ast::OpenParen,
pub restriction: T,
pub close: ast::CloseParen,
}