1use proc_macro2::TokenStream;
9use proc_macro_error2::emit_error;
10use quote::{ToTokens, TokenStreamExt};
11use syn::parse::{Parse, ParseStream, Result};
12use syn::punctuated::Punctuated;
13use syn::{token, Attribute, Expr, Ident, Token, Type, Visibility};
14
15#[derive(Debug)]
17pub enum StructStyle {
18 Unit(Token![;]),
20 Tuple(token::Paren, Token![;]),
22 Regular(token::Brace),
24}
25
26#[derive(Debug)]
30pub enum Fields {
31 Named(FieldsNamed),
33 Unnamed(FieldsUnnamed),
35 Unit,
37}
38
39#[derive(Debug)]
43pub struct FieldsNamed {
44 pub brace_token: token::Brace,
46 pub fields: Punctuated<Field, Token![,]>,
48}
49
50#[derive(Debug)]
54pub struct FieldsUnnamed {
55 pub paren_token: token::Paren,
57 pub fields: Punctuated<Field, Token![,]>,
59}
60
61#[derive(Debug)]
65pub struct Field {
66 pub attrs: Vec<Attribute>,
68 pub vis: Visibility,
70 pub ident: Option<Ident>,
72 pub colon_token: Option<Token![:]>,
74 pub ty: Type,
76 pub assign: Option<(Token![=], Expr)>,
82}
83
84pub(crate) mod parsing {
86 use super::*;
87 use syn::ext::IdentExt;
88 use syn::{braced, parenthesized, WhereClause};
89
90 impl Parse for FieldsNamed {
91 fn parse(input: ParseStream) -> Result<Self> {
92 let content;
93 let brace_token = braced!(content in input);
94 Ok(FieldsNamed {
95 brace_token,
96 fields: content.parse_terminated(Field::parse_named, Token![,])?,
97 })
98 }
99 }
100
101 impl Parse for FieldsUnnamed {
102 fn parse(input: ParseStream) -> Result<Self> {
103 let content;
104 let paren_token = parenthesized!(content in input);
105 Ok(FieldsUnnamed {
106 paren_token,
107 fields: content.parse_terminated(Field::parse_unnamed, Token![,])?,
108 })
109 }
110 }
111
112 impl Field {
113 pub fn parse_named(input: ParseStream) -> Result<Self> {
115 Ok(Field {
116 attrs: input.call(Attribute::parse_outer)?,
117 vis: input.parse()?,
118 ident: Some(if input.peek(Token![_]) {
119 input.call(Ident::parse_any)
120 } else {
121 input.parse()
122 }?),
123 colon_token: Some(input.parse()?),
124 ty: input.parse()?,
125 assign: if input.peek(Token![=]) {
126 Some((input.parse()?, input.parse()?))
127 } else {
128 None
129 },
130 })
131 }
132
133 pub fn parse_unnamed(input: ParseStream) -> Result<Self> {
135 Ok(Field {
136 attrs: input.call(Attribute::parse_outer)?,
137 vis: input.parse()?,
138 ident: None,
139 colon_token: None,
140 ty: input.parse()?,
141 assign: if input.peek(Token![=]) {
142 Some((input.parse()?, input.parse()?))
143 } else {
144 None
145 },
146 })
147 }
148 }
149
150 pub(crate) fn data_struct(
151 input: ParseStream,
152 ) -> Result<(Option<WhereClause>, Fields, Option<Token![;]>)> {
153 let mut lookahead = input.lookahead1();
154 let mut where_clause = None;
155 if lookahead.peek(Token![where]) {
156 where_clause = Some(input.parse()?);
157 lookahead = input.lookahead1();
158 }
159
160 if where_clause.is_none() && lookahead.peek(token::Paren) {
161 let fields = input.parse()?;
162
163 lookahead = input.lookahead1();
164 if lookahead.peek(Token![where]) {
165 where_clause = Some(input.parse()?);
166 lookahead = input.lookahead1();
167 }
168
169 if lookahead.peek(Token![;]) {
170 let semi = input.parse()?;
171 Ok((where_clause, Fields::Unnamed(fields), Some(semi)))
172 } else {
173 Err(lookahead.error())
174 }
175 } else if lookahead.peek(token::Brace) {
176 let fields = parse_braced(input)?;
177 Ok((where_clause, Fields::Named(fields), None))
178 } else if lookahead.peek(Token![;]) {
179 let semi = input.parse()?;
180 Ok((where_clause, Fields::Unit, Some(semi)))
181 } else {
182 Err(lookahead.error())
183 }
184 }
185
186 fn parse_braced(input: ParseStream) -> Result<FieldsNamed> {
187 let content;
188 let brace_token = braced!(content in input);
189 let fields = content.parse_terminated(Field::parse_named, Token![,])?;
190 Ok(FieldsNamed {
191 brace_token,
192 fields,
193 })
194 }
195}
196
197mod printing {
198 use super::*;
199
200 impl ToTokens for FieldsNamed {
201 fn to_tokens(&self, tokens: &mut TokenStream) {
202 self.brace_token.surround(tokens, |tokens| {
203 self.fields.to_tokens(tokens);
204 });
205 }
206 }
207
208 impl ToTokens for FieldsUnnamed {
209 fn to_tokens(&self, tokens: &mut TokenStream) {
210 self.paren_token.surround(tokens, |tokens| {
211 self.fields.to_tokens(tokens);
212 });
213 }
214 }
215
216 impl ToTokens for Field {
217 fn to_tokens(&self, tokens: &mut TokenStream) {
218 tokens.append_all(&self.attrs);
219 self.vis.to_tokens(tokens);
220 if let Some(ident) = &self.ident {
221 ident.to_tokens(tokens);
222 self.colon_token.unwrap_or_default().to_tokens(tokens);
223 }
224 self.ty.to_tokens(tokens);
225
226 if let Some(ref assign) = self.assign {
227 emit_error!(
228 assign.0,
229 "default value on `struct` field in output";
230 help = "did you mean to use the `#[impl_default]` attribute?",
231 );
232 }
233 }
234 }
235}