2 use crate::punctuated
::Punctuated
;
7 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
9 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
11 /// Attributes tagged on the variant.
12 pub attrs
: Vec
<Attribute
>,
14 /// Name of the variant.
17 /// Content stored in the variant.
20 /// Explicit discriminant: `Variant = 1`
21 pub discriminant
: Option
<(Token
![=], Expr
)>,
25 ast_enum_of_structs
! {
26 /// Data stored within an enum variant or struct.
28 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
31 /// # Syntax tree enum
33 /// This type is a [syntax tree enum].
35 /// [syntax tree enum]: Expr#syntax-tree-enums
36 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
38 /// Named fields of a struct or struct variant such as `Point { x: f64,
42 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
43 Unnamed(FieldsUnnamed
),
45 /// Unit struct or unit variant such as `None`.
51 /// Named fields of a struct or struct variant such as `Point { x: f64,
54 /// *This type is available only if Syn is built with the `"derive"` or
55 /// `"full"` feature.*
56 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
57 pub struct FieldsNamed
{
58 pub brace_token
: token
::Brace
,
59 pub named
: Punctuated
<Field
, Token
![,]>,
64 /// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
66 /// *This type is available only if Syn is built with the `"derive"` or
67 /// `"full"` feature.*
68 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
69 pub struct FieldsUnnamed
{
70 pub paren_token
: token
::Paren
,
71 pub unnamed
: Punctuated
<Field
, Token
![,]>,
76 /// Get an iterator over the borrowed [`Field`] items in this object. This
77 /// iterator can be used to iterate over a named or unnamed struct or
78 /// variant's fields uniformly.
79 pub fn iter(&self) -> punctuated
::Iter
<Field
> {
81 Fields
::Unit
=> crate::punctuated
::empty_punctuated_iter(),
82 Fields
::Named(f
) => f
.named
.iter(),
83 Fields
::Unnamed(f
) => f
.unnamed
.iter(),
87 /// Get an iterator over the mutably borrowed [`Field`] items in this
88 /// object. This iterator can be used to iterate over a named or unnamed
89 /// struct or variant's fields uniformly.
90 pub fn iter_mut(&mut self) -> punctuated
::IterMut
<Field
> {
92 Fields
::Unit
=> crate::punctuated
::empty_punctuated_iter_mut(),
93 Fields
::Named(f
) => f
.named
.iter_mut(),
94 Fields
::Unnamed(f
) => f
.unnamed
.iter_mut(),
98 /// Returns the number of fields.
99 pub fn len(&self) -> usize {
102 Fields
::Named(f
) => f
.named
.len(),
103 Fields
::Unnamed(f
) => f
.unnamed
.len(),
107 /// Returns `true` if there are zero fields.
108 pub fn is_empty(&self) -> bool
{
110 Fields
::Unit
=> true,
111 Fields
::Named(f
) => f
.named
.is_empty(),
112 Fields
::Unnamed(f
) => f
.unnamed
.is_empty(),
117 impl IntoIterator
for Fields
{
119 type IntoIter
= punctuated
::IntoIter
<Field
>;
121 fn into_iter(self) -> Self::IntoIter
{
123 Fields
::Unit
=> Punctuated
::<Field
, ()>::new().into_iter(),
124 Fields
::Named(f
) => f
.named
.into_iter(),
125 Fields
::Unnamed(f
) => f
.unnamed
.into_iter(),
130 impl<'a
> IntoIterator
for &'a Fields
{
131 type Item
= &'a Field
;
132 type IntoIter
= punctuated
::Iter
<'a
, Field
>;
134 fn into_iter(self) -> Self::IntoIter
{
139 impl<'a
> IntoIterator
for &'a
mut Fields
{
140 type Item
= &'a
mut Field
;
141 type IntoIter
= punctuated
::IterMut
<'a
, Field
>;
143 fn into_iter(self) -> Self::IntoIter
{
149 /// A field of a struct or enum variant.
151 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
153 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
155 /// Attributes tagged on the field.
156 pub attrs
: Vec
<Attribute
>,
158 /// Visibility of the field.
161 /// Name of the field, if any.
163 /// Fields of tuple structs have no names.
164 pub ident
: Option
<Ident
>,
166 pub colon_token
: Option
<Token
![:]>,
168 /// Type of the field.
173 ast_enum_of_structs
! {
174 /// The visibility level of an item: inherited or `pub` or
175 /// `pub(restricted)`.
177 /// *This type is available only if Syn is built with the `"derive"` or `"full"`
180 /// # Syntax tree enum
182 /// This type is a [syntax tree enum].
184 /// [syntax tree enum]: Expr#syntax-tree-enums
185 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
186 pub enum Visibility
{
187 /// A public visibility level: `pub`.
190 /// A crate-level visibility: `crate`.
193 /// A visibility level restricted to some path: `pub(self)` or
194 /// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
195 Restricted(VisRestricted
),
197 /// An inherited visibility, which usually means private.
203 /// A public visibility level: `pub`.
205 /// *This type is available only if Syn is built with the `"derive"` or
206 /// `"full"` feature.*
207 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
208 pub struct VisPublic
{
209 pub pub_token
: Token
![pub],
214 /// A crate-level visibility: `crate`.
216 /// *This type is available only if Syn is built with the `"derive"` or
217 /// `"full"` feature.*
218 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
219 pub struct VisCrate
{
220 pub crate_token
: Token
![crate],
225 /// A visibility level restricted to some path: `pub(self)` or
226 /// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
228 /// *This type is available only if Syn is built with the `"derive"` or
229 /// `"full"` feature.*
230 #[cfg_attr(doc_cfg, doc(cfg(any(feature = "full", feature = "derive"))))]
231 pub struct VisRestricted
{
232 pub pub_token
: Token
![pub],
233 pub paren_token
: token
::Paren
,
234 pub in_token
: Option
<Token
![in]>,
239 #[cfg(feature = "parsing")]
242 use crate::ext
::IdentExt
;
243 use crate::parse
::discouraged
::Speculative
;
244 use crate::parse
::{Parse, ParseStream, Result}
;
246 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
247 impl Parse
for Variant
{
248 fn parse(input
: ParseStream
) -> Result
<Self> {
249 let attrs
= input
.call(Attribute
::parse_outer
)?
;
250 let _visibility
: Visibility
= input
.parse()?
;
251 let ident
: Ident
= input
.parse()?
;
252 let fields
= if input
.peek(token
::Brace
) {
253 Fields
::Named(input
.parse()?
)
254 } else if input
.peek(token
::Paren
) {
255 Fields
::Unnamed(input
.parse()?
)
259 let discriminant
= if input
.peek(Token
![=]) {
260 let eq_token
: Token
![=] = input
.parse()?
;
261 let discriminant
: Expr
= input
.parse()?
;
262 Some((eq_token
, discriminant
))
275 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
276 impl Parse
for FieldsNamed
{
277 fn parse(input
: ParseStream
) -> Result
<Self> {
280 brace_token
: braced
!(content
in input
),
281 named
: content
.parse_terminated(Field
::parse_named
)?
,
286 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
287 impl Parse
for FieldsUnnamed
{
288 fn parse(input
: ParseStream
) -> Result
<Self> {
291 paren_token
: parenthesized
!(content
in input
),
292 unnamed
: content
.parse_terminated(Field
::parse_unnamed
)?
,
298 /// Parses a named (braced struct) field.
299 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
300 pub fn parse_named(input
: ParseStream
) -> Result
<Self> {
302 attrs
: input
.call(Attribute
::parse_outer
)?
,
304 ident
: Some(if input
.peek(Token
![_
]) {
305 input
.call(Ident
::parse_any
)
309 colon_token
: Some(input
.parse()?
),
314 /// Parses an unnamed (tuple struct) field.
315 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
316 pub fn parse_unnamed(input
: ParseStream
) -> Result
<Self> {
318 attrs
: input
.call(Attribute
::parse_outer
)?
,
327 #[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
328 impl Parse
for Visibility
{
329 fn parse(input
: ParseStream
) -> Result
<Self> {
330 // Recognize an empty None-delimited group, as produced by a $:vis
331 // matcher that matched no tokens.
332 if input
.peek(token
::Group
) {
333 let ahead
= input
.fork();
334 let group
= crate::group
::parse_group(&ahead
)?
;
335 if group
.content
.is_empty() {
336 input
.advance_to(&ahead
);
337 return Ok(Visibility
::Inherited
);
341 if input
.peek(Token
![pub]) {
342 Self::parse_pub(input
)
343 } else if input
.peek(Token
![crate]) {
344 Self::parse_crate(input
)
346 Ok(Visibility
::Inherited
)
352 fn parse_pub(input
: ParseStream
) -> Result
<Self> {
353 let pub_token
= input
.parse
::<Token
![pub]>()?
;
355 if input
.peek(token
::Paren
) {
356 let ahead
= input
.fork();
359 let paren_token
= parenthesized
!(content
in ahead
);
360 if content
.peek(Token
![crate])
361 || content
.peek(Token
![self])
362 || content
.peek(Token
![super])
364 let path
= content
.call(Ident
::parse_any
)?
;
366 // Ensure there are no additional tokens within `content`.
367 // Without explicitly checking, we may misinterpret a tuple
368 // field as a restricted visibility, causing a parse error.
369 // e.g. `pub (crate::A, crate::B)` (Issue #720).
370 if content
.is_empty() {
371 input
.advance_to(&ahead
);
372 return Ok(Visibility
::Restricted(VisRestricted
{
376 path
: Box
::new(Path
::from(path
)),
379 } else if content
.peek(Token
![in]) {
380 let in_token
: Token
![in] = content
.parse()?
;
381 let path
= content
.call(Path
::parse_mod_style
)?
;
383 input
.advance_to(&ahead
);
384 return Ok(Visibility
::Restricted(VisRestricted
{
387 in_token
: Some(in_token
),
388 path
: Box
::new(path
),
393 Ok(Visibility
::Public(VisPublic { pub_token }
))
396 fn parse_crate(input
: ParseStream
) -> Result
<Self> {
397 if input
.peek2(Token
![::]) {
398 Ok(Visibility
::Inherited
)
400 Ok(Visibility
::Crate(VisCrate
{
401 crate_token
: input
.parse()?
,
406 #[cfg(feature = "full")]
407 pub(crate) fn is_some(&self) -> bool
{
409 Visibility
::Inherited
=> false,
416 #[cfg(feature = "printing")]
419 use crate::print
::TokensOrDefault
;
420 use proc_macro2
::TokenStream
;
421 use quote
::{ToTokens, TokenStreamExt}
;
423 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
424 impl ToTokens
for Variant
{
425 fn to_tokens(&self, tokens
: &mut TokenStream
) {
426 tokens
.append_all(&self.attrs
);
427 self.ident
.to_tokens(tokens
);
428 self.fields
.to_tokens(tokens
);
429 if let Some((eq_token
, disc
)) = &self.discriminant
{
430 eq_token
.to_tokens(tokens
);
431 disc
.to_tokens(tokens
);
436 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
437 impl ToTokens
for FieldsNamed
{
438 fn to_tokens(&self, tokens
: &mut TokenStream
) {
439 self.brace_token
.surround(tokens
, |tokens
| {
440 self.named
.to_tokens(tokens
);
445 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
446 impl ToTokens
for FieldsUnnamed
{
447 fn to_tokens(&self, tokens
: &mut TokenStream
) {
448 self.paren_token
.surround(tokens
, |tokens
| {
449 self.unnamed
.to_tokens(tokens
);
454 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
455 impl ToTokens
for Field
{
456 fn to_tokens(&self, tokens
: &mut TokenStream
) {
457 tokens
.append_all(&self.attrs
);
458 self.vis
.to_tokens(tokens
);
459 if let Some(ident
) = &self.ident
{
460 ident
.to_tokens(tokens
);
461 TokensOrDefault(&self.colon_token
).to_tokens(tokens
);
463 self.ty
.to_tokens(tokens
);
467 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
468 impl ToTokens
for VisPublic
{
469 fn to_tokens(&self, tokens
: &mut TokenStream
) {
470 self.pub_token
.to_tokens(tokens
);
474 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
475 impl ToTokens
for VisCrate
{
476 fn to_tokens(&self, tokens
: &mut TokenStream
) {
477 self.crate_token
.to_tokens(tokens
);
481 #[cfg_attr(doc_cfg, doc(cfg(feature = "printing")))]
482 impl ToTokens
for VisRestricted
{
483 fn to_tokens(&self, tokens
: &mut TokenStream
) {
484 self.pub_token
.to_tokens(tokens
);
485 self.paren_token
.surround(tokens
, |tokens
| {
486 // TODO: If we have a path which is not "self" or "super" or
487 // "crate", automatically add the "in" token.
488 self.in_token
.to_tokens(tokens
);
489 self.path
.to_tokens(tokens
);