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(Debug, TryClone, PartialEq, Eq, ToTokens, OptionSpanned)]
44#[non_exhaustive]
45pub enum Visibility {
46 Inherited,
48 Public(T![pub]),
50 Crate(VisibilityRestrict<T![crate]>),
52 Super(VisibilityRestrict<T![super]>),
54 SelfValue(VisibilityRestrict<T![self]>),
56 In(VisibilityRestrict<VisibilityIn>),
58}
59
60impl Visibility {
61 pub const fn is_inherited(&self) -> bool {
63 matches!(self, Visibility::Inherited)
64 }
65
66 pub const fn is_public(&self) -> bool {
68 matches!(self, Visibility::Public(..))
69 }
70}
71
72impl Default for Visibility {
73 fn default() -> Self {
74 Self::Inherited
75 }
76}
77
78impl Parse for Visibility {
79 fn parse(parser: &mut Parser<'_>) -> Result<Self> {
80 let pub_token = match parser.parse::<Option<T![pub]>>()? {
81 Some(pub_token) => pub_token,
82 None => return Ok(Self::Inherited),
83 };
84
85 let open = match parser.parse::<Option<ast::OpenParen>>()? {
86 Some(open) => open,
87 None => return Ok(Self::Public(pub_token)),
88 };
89
90 Ok(match parser.nth(0)? {
91 K![in] => Self::In(VisibilityRestrict {
92 pub_token,
93 open,
94 restriction: VisibilityIn {
95 in_token: parser.parse()?,
96 path: parser.parse()?,
97 },
98 close: parser.parse()?,
99 }),
100 K![super] => Self::Super(VisibilityRestrict {
101 pub_token,
102 open,
103 restriction: parser.parse()?,
104 close: parser.parse()?,
105 }),
106 K![self] => Self::SelfValue(VisibilityRestrict {
107 pub_token,
108 open,
109 restriction: parser.parse()?,
110 close: parser.parse()?,
111 }),
112 _ => Self::Crate(VisibilityRestrict {
113 pub_token,
114 open,
115 restriction: parser.parse()?,
116 close: parser.parse()?,
117 }),
118 })
119 }
120}
121
122#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
124#[non_exhaustive]
125pub struct VisibilityIn {
126 pub in_token: T![in],
128 pub path: ast::Path,
130}
131
132#[derive(Debug, TryClone, PartialEq, Eq, ToTokens, Spanned)]
134#[non_exhaustive]
135#[try_clone(bound = {T: TryClone})]
136pub struct VisibilityRestrict<T> {
137 pub pub_token: ast::generated::Pub,
139 pub open: ast::OpenParen,
141 pub restriction: T,
143 pub close: ast::CloseParen,
145}