1use crate::path::Path;
2use crate::token;
3
4ast_enum! {
5 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
14 pub enum Visibility {
15 Public(Token![pub]),
17
18 Restricted(VisRestricted),
21
22 Inherited,
24 }
25}
26
27ast_struct! {
28 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
31 pub struct VisRestricted {
32 pub pub_token: Token![pub],
33 pub paren_token: token::Paren,
34 pub in_token: Option<Token![in]>,
35 pub path: Box<Path>,
36 }
37}
38
39ast_enum! {
40 #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
42 #[non_exhaustive]
43 pub enum FieldMutability {
44 None,
45
46 }
57}
58
59#[cfg(feature = "parsing")]
60pub(crate) mod parsing {
61 use crate::error::Result;
62 use crate::ext::IdentExt as _;
63 use crate::ident::Ident;
64 use crate::parse::discouraged::Speculative as _;
65 use crate::parse::{Parse, ParseStream};
66 use crate::path::Path;
67 use crate::restriction::{VisRestricted, Visibility};
68 use crate::token;
69
70 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
71 impl Parse for Visibility {
72 fn parse(input: ParseStream) -> Result<Self> {
73 if input.peek(token::Group) {
76 let ahead = input.fork();
77 let group = crate::group::parse_group(&ahead)?;
78 if group.content.is_empty() {
79 input.advance_to(&ahead);
80 return Ok(Visibility::Inherited);
81 }
82 }
83
84 if input.peek(Token![pub]) {
85 Self::parse_pub(input)
86 } else {
87 Ok(Visibility::Inherited)
88 }
89 }
90 }
91
92 impl Visibility {
93 fn parse_pub(input: ParseStream) -> Result<Self> {
94 let pub_token = input.parse::<Token![pub]>()?;
95
96 if input.peek(token::Paren) {
97 let ahead = input.fork();
98
99 let content;
100 let paren_token = parenthesized!(content in ahead);
101 if content.peek(Token![crate])
102 || content.peek(Token![self])
103 || content.peek(Token![super])
104 {
105 let path = content.call(Ident::parse_any)?;
106
107 if content.is_empty() {
112 input.advance_to(&ahead);
113 return Ok(Visibility::Restricted(VisRestricted {
114 pub_token,
115 paren_token,
116 in_token: None,
117 path: Box::new(Path::from(path)),
118 }));
119 }
120 } else if content.peek(Token![in]) {
121 let in_token: Token![in] = content.parse()?;
122 let path = content.call(Path::parse_mod_style)?;
123
124 input.advance_to(&ahead);
125 return Ok(Visibility::Restricted(VisRestricted {
126 pub_token,
127 paren_token,
128 in_token: Some(in_token),
129 path: Box::new(path),
130 }));
131 }
132 }
133
134 Ok(Visibility::Public(pub_token))
135 }
136
137 #[cfg(feature = "full")]
138 pub(crate) fn is_some(&self) -> bool {
139 match self {
140 Visibility::Inherited => false,
141 _ => true,
142 }
143 }
144 }
145}
146
147#[cfg(feature = "printing")]
148mod printing {
149 use crate::path;
150 use crate::path::printing::PathStyle;
151 use crate::restriction::{VisRestricted, Visibility};
152 use proc_macro2::TokenStream;
153 use quote::ToTokens;
154
155 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
156 impl ToTokens for Visibility {
157 fn to_tokens(&self, tokens: &mut TokenStream) {
158 match self {
159 Visibility::Public(pub_token) => pub_token.to_tokens(tokens),
160 Visibility::Restricted(vis_restricted) => vis_restricted.to_tokens(tokens),
161 Visibility::Inherited => {}
162 }
163 }
164 }
165
166 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
167 impl ToTokens for VisRestricted {
168 fn to_tokens(&self, tokens: &mut TokenStream) {
169 self.pub_token.to_tokens(tokens);
170 self.paren_token.surround(tokens, |tokens| {
171 self.in_token.to_tokens(tokens);
174 path::printing::print_path(tokens, &self.path, PathStyle::Mod);
175 });
176 }
177 }
178}