1use crate::ast::prelude::*;
2
3#[test]
4#[cfg(not(miri))]
5fn ast_parse() {
6 assert!(matches! {
7 rt::<ast::Visibility>("pub"),
8 ast::Visibility::Public(_)
9 });
10
11 assert!(matches! {
12 rt::<ast::Visibility>("pub (in a::b::c)"),
13 ast::Visibility::In(_)
14 });
15
16 assert!(matches! {
17 rt::<ast::Visibility>("pub(in crate::x::y::z)"),
18 ast::Visibility::In(_)
19 });
20
21 assert!(matches! {
22 rt::<ast::Visibility>("pub(super)"),
23 ast::Visibility::Super(_)
24 });
25
26 assert!(matches! {
27 rt::<ast::Visibility>("pub(crate)"),
28 ast::Visibility::Crate(_)
29 });
30
31 assert!(matches! {
32 rt::<ast::Visibility>("pub(self)"),
33 ast::Visibility::SelfValue(_)
34 });
35}
36
37#[derive(Default, Debug, TryClone, PartialEq, Eq, ToTokens, OptionSpanned)]
44#[non_exhaustive]
45pub enum Visibility {
46 #[default]
48 Inherited,
49 Public(T![pub]),
51 Crate(VisibilityRestrict<T![crate]>),
53 Super(VisibilityRestrict<T![super]>),
55 SelfValue(VisibilityRestrict<T![self]>),
57 In(VisibilityRestrict<VisibilityIn>),
59}
60
61impl Visibility {
62 pub const fn is_inherited(&self) -> bool {
64 matches!(self, Visibility::Inherited)
65 }
66
67 pub const fn is_public(&self) -> bool {
69 matches!(self, Visibility::Public(..))
70 }
71}
72
73impl Parse for Visibility {
74 fn parse(parser: &mut Parser<'_>) -> Result<Self> {
75 let pub_token = match parser.parse::<Option<T![pub]>>()? {
76 Some(pub_token) => pub_token,
77 None => return Ok(Self::Inherited),
78 };
79
80 let open = match parser.parse::<Option<ast::OpenParen>>()? {
81 Some(open) => open,
82 None => return Ok(Self::Public(pub_token)),
83 };
84
85 Ok(match parser.nth(0)? {
86 K![in] => Self::In(VisibilityRestrict {
87 pub_token,
88 open,
89 restriction: VisibilityIn {
90 in_token: parser.parse()?,
91 path: parser.parse()?,
92 },
93 close: parser.parse()?,
94 }),
95 K![super] => Self::Super(VisibilityRestrict {
96 pub_token,
97 open,
98 restriction: parser.parse()?,
99 close: parser.parse()?,
100 }),
101 K![self] => Self::SelfValue(VisibilityRestrict {
102 pub_token,
103 open,
104 restriction: parser.parse()?,
105 close: parser.parse()?,
106 }),
107 _ => Self::Crate(VisibilityRestrict {
108 pub_token,
109 open,
110 restriction: parser.parse()?,
111 close: parser.parse()?,
112 }),
113 })
114 }
115}
116
117#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
119#[non_exhaustive]
120pub struct VisibilityIn {
121 pub in_token: T![in],
123 pub path: ast::Path,
125}
126
127#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
129#[non_exhaustive]
130#[try_clone(bound = {T: TryClone})]
131pub struct VisibilityRestrict<T> {
132 pub pub_token: ast::generated::Pub,
134 pub open: ast::OpenParen,
136 pub restriction: T,
138 pub close: ast::CloseParen,
140}