diff --git a/src/parse_quote.rs b/src/parse_quote.rs index 59e51b41e..18de47450 100644 --- a/src/parse_quote.rs +++ b/src/parse_quote.rs @@ -136,7 +136,7 @@ impl ParseQuote for T { use crate::punctuated::Punctuated; #[cfg(any(feature = "full", feature = "derive"))] -use crate::{attr, Attribute}; +use crate::{attr, Attribute, Field, FieldMutability, Ident, Type, Visibility}; #[cfg(feature = "full")] use crate::{Block, Pat, Stmt}; @@ -151,6 +151,36 @@ impl ParseQuote for Attribute { } } +#[cfg(any(feature = "full", feature = "derive"))] +impl ParseQuote for Field { + fn parse(input: ParseStream) -> Result { + let attrs = input.call(Attribute::parse_outer)?; + let vis: Visibility = input.parse()?; + + let ident: Option; + let colon_token: Option; + let is_named = input.peek(Ident) && input.peek2(Token![:]) && !input.peek2(Token![::]); + if is_named { + ident = Some(input.parse()?); + colon_token = Some(input.parse()?); + } else { + ident = None; + colon_token = None; + } + + let ty: Type = input.parse()?; + + Ok(Field { + attrs, + vis, + mutability: FieldMutability::None, + ident, + colon_token, + ty, + }) + } +} + #[cfg(feature = "full")] impl ParseQuote for Pat { fn parse(input: ParseStream) -> Result { diff --git a/tests/test_parse_quote.rs b/tests/test_parse_quote.rs index 1c9120646..dff0c2ccc 100644 --- a/tests/test_parse_quote.rs +++ b/tests/test_parse_quote.rs @@ -2,7 +2,7 @@ mod macros; use syn::punctuated::Punctuated; -use syn::{parse_quote, Attribute, Lit, Pat, Stmt, Token}; +use syn::{parse_quote, Attribute, Field, Lit, Pat, Stmt, Token}; #[test] fn test_attribute() { @@ -35,6 +35,46 @@ fn test_attribute() { "###); } +#[test] +fn test_field() { + let field: Field = parse_quote!(pub enabled: bool); + snapshot!(field, @r###" + Field { + vis: Visibility::Public, + ident: Some("enabled"), + colon_token: Some, + ty: Type::Path { + path: Path { + segments: [ + PathSegment { + ident: "bool", + }, + ], + }, + }, + } + "###); + + let field: Field = parse_quote!(primitive::bool); + snapshot!(field, @r###" + Field { + vis: Visibility::Inherited, + ty: Type::Path { + path: Path { + segments: [ + PathSegment { + ident: "primitive", + }, + PathSegment { + ident: "bool", + }, + ], + }, + }, + } + "###); +} + #[test] fn test_pat() { let pat: Pat = parse_quote!(Some(false) | None);