1use crate::*;
2
3use std::fmt::Write;
4use std::{cmp, hash};
5
6use arrayvec::ArrayString;
7
8use syn::{
9 self, Attribute, Data, DeriveInput, Field as SynField, Fields as SynFields, Generics, Ident,
10 Type, Visibility,
11};
12
13use quote::ToTokens;
14
15use proc_macro2::{Span, TokenStream};
16
17mod field_map;
18
19pub(crate) use self::field_map::FieldMap;
20
21#[derive(Clone, Debug, PartialEq, Hash)]
24pub(crate) struct DataStructure<'a> {
25 pub(crate) vis: &'a Visibility,
26 pub(crate) name: &'a Ident,
27 pub(crate) generics: &'a Generics,
28 pub(crate) lifetime_count: usize,
29 pub(crate) field_count: usize,
30 pub(crate) pub_field_count: usize,
31 pub(crate) attrs: &'a [Attribute],
36
37 pub(crate) data_variant: DataVariant,
38 pub(crate) enum_: Option<Enum<'a>>,
39 pub(crate) variants: Vec<Struct<'a>>,
40}
41
42#[derive(Clone, Debug)]
43pub(crate) struct Enum<'a> {
44 pub(crate) name: &'a Ident,
45 pub(crate) path: TokenStream,
46}
47
48impl<'a> cmp::PartialEq for Enum<'a> {
49 fn eq(&self, other: &Self) -> bool {
50 self.name == other.name
51 }
52}
53
54impl<'a> hash::Hash for Enum<'a> {
55 fn hash<H>(&self, hasher: &mut H)
56 where
57 H: hash::Hasher,
58 {
59 self.name.hash(hasher);
60 }
61}
62
63impl<'a> DataStructure<'a> {
64 pub(crate) fn new(
65 ast: &'a mut DeriveInput,
66 _arenas: &'a Arenas,
67 ) -> Self {
68 let name = &ast.ident;
69 let enum_ = match ast.data {
70 Data::Enum(_) => Some(Enum {
71 name,
72 path: quote! { #name:: },
73 }),
74 _ => None,
75 };
76
77 let data_variant: DataVariant;
78
79 let mut variants = Vec::new();
82
83
84 match &mut ast.data {
85 Data::Enum(enum_) => {
86 let override_vis=Some(&ast.vis);
87
88 for (variant,var) in (&mut enum_.variants).into_iter().enumerate() {
89 variants.push(Struct::new(
90 StructParams{
91 discriminant:var.discriminant
92 .as_ref()
93 .map(|(_,v)| v ),
94 variant:variant,
95 attrs:&var.attrs,
96 name:&var.ident,
97 override_vis:override_vis,
98 },
99 &mut var.fields,
100 ));
102 }
103 data_variant = DataVariant::Enum;
104 }
105 Data::Struct(struct_) => {
106 let override_vis=None;
107
108 variants.push(Struct::new(
109 StructParams{
110 discriminant:None,
111 variant:0,
112 attrs:&[],
113 name:name,
114 override_vis:override_vis,
115 },
116 &mut struct_.fields,
117 ));
119 data_variant = DataVariant::Struct;
120 }
121
122 Data::Union(union_) => {
123 let override_vis=None;
124
125 let fields = Some(&union_.fields.named);
126 let sk = StructKind::Braced;
127 let vari = Struct::with_fields(
128 StructParams{
129 discriminant:None,
130 variant:0,
131 attrs:&[],
132 name:name,
133 override_vis:override_vis,
134 },
135 sk,
136 fields,
137 );
139 variants.push(vari);
140 data_variant = DataVariant::Union;
141 }
142 }
143
144 let mut field_count=0;
145 let mut pub_field_count=0;
146 for vari in &variants {
149 field_count+=vari.fields.len();
150 pub_field_count+=vari.pub_field_count;
151 }
153
154 Self {
155 vis: &ast.vis,
156 name,
157 attrs: &ast.attrs,
159 generics: &ast.generics,
160 lifetime_count:ast.generics.lifetimes().count(),
161 data_variant,
162 enum_,
163 variants,
164 field_count,
165 pub_field_count,
166 }
168 }
169
170 pub(crate) fn has_public_fields(&self)->bool{
171 self.pub_field_count!=0
172 }
173}
174
175#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
179pub(crate) enum StructKind {
180 Tuple,
182 Braced,
184}
185
186#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
187pub(crate) enum DataVariant {
188 Struct,
189 Enum,
190 Union,
191}
192
193
194#[derive(Copy,Clone, Debug, PartialEq, Hash)]
195pub(crate) struct FieldIndex {
196 pub(crate) variant:usize,
197 pub(crate) pos:usize,
198}
199
200#[derive(Copy,Clone)]
204pub(crate) struct StructParams<'a>{
205 pub(crate) discriminant:Option<&'a syn::Expr>,
206 pub(crate) variant:usize,
207 pub(crate) attrs: &'a [Attribute],
208 pub(crate) name: &'a Ident,
209 pub(crate) override_vis:Option<&'a Visibility>,
210}
211
212
213#[derive(Clone, Debug, PartialEq, Hash)]
214pub(crate) struct Struct<'a> {
215 pub(crate) attrs: &'a [Attribute],
216 pub(crate) name: &'a Ident,
217 pub(crate) kind: StructKind,
218 pub(crate) fields: Vec<Field<'a>>,
219 pub(crate) pub_field_count:usize,
220 pub(crate) discriminant:Option<&'a syn::Expr>,
222 _priv: (),
223}
224
225impl<'a> Struct<'a> {
226 pub(crate) fn new(
227 p:StructParams<'a>,
228 fields: &'a SynFields,
229 ) -> Self {
231 let kind = match *fields {
232 SynFields::Named { .. } => StructKind::Braced,
233 SynFields::Unnamed { .. } => StructKind::Tuple,
234 SynFields::Unit { .. } => StructKind::Braced,
235 };
236 let fields = match fields {
237 SynFields::Named(f) => Some(&f.named),
238 SynFields::Unnamed(f) => Some(&f.unnamed),
239 SynFields::Unit => None,
240 };
241
242 Self::with_fields(p, kind, fields)
243 }
245
246 pub(crate) fn with_fields<I>(
247 p:StructParams<'a>,
248 kind: StructKind,
249 fields: Option<I>,
250 ) -> Self
252 where
253 I: IntoIterator<Item = &'a SynField>,
254 {
255 let fields=match fields {
256 Some(x) => Field::from_iter(p, x),
257 None => Vec::new(),
259 };
260
261 let mut pub_field_count=0usize;
262 for field in &fields {
265 if field.is_public() {
266 pub_field_count+=1;
267 }
268 }
270
271 Self {
272 discriminant:p.discriminant,
273 attrs:p.attrs,
274 name:p.name,
275 kind,
276 pub_field_count,
277 fields,
279 _priv: (),
280 }
281 }
282
283 }
284
285#[derive(Clone, Debug, PartialEq, Hash)]
290pub(crate) struct Field<'a> {
291 pub(crate) index:FieldIndex,
292 pub(crate) attrs: &'a [Attribute],
293 pub(crate) vis: &'a Visibility,
294 pub(crate) ident: FieldIdent<'a>,
297 pub(crate) ty: &'a Type,
298 }
307
308impl<'a> Field<'a> {
309 pub(crate) fn new(
310 index: FieldIndex,
311 field: &'a SynField,
312 span: Span,
313 override_vis:Option<&'a Visibility>,
314 ) -> Self {
316 let ident = match field.ident.as_ref() {
317 Some(ident) => FieldIdent::Named(ident),
318 None => FieldIdent::new_index(index.pos, span),
319 };
320
321 Self {
331 index,
332 attrs: &field.attrs,
333 vis: override_vis.unwrap_or(&field.vis),
334 ident,
336 ty: &field.ty,
337 }
341 }
342
343 pub(crate) fn is_public(&self)->bool{
344 match self.vis {
345 Visibility::Public{..}=>true,
346 _=>false,
347 }
348 }
349
350
351 pub(crate) fn ident(&self)->&Ident{
352 match &self.ident {
353 FieldIdent::Index(_,ident)=>ident,
354 FieldIdent::Named(ident)=>ident,
355 }
356 }
357
358 pub(crate) fn from_iter<I>(
359 p:StructParams<'a>,
360 fields: I,
361 ) -> Vec<Self>
363 where
364 I: IntoIterator<Item = &'a SynField>,
365 {
366 fields
367 .into_iter()
368 .enumerate()
369 .map(|(pos, f)|{
370 let fi=FieldIndex{variant:p.variant,pos};
371 Field::new(fi, f, p.name.span(),p.override_vis)
373 })
374 .collect()
375 }
376}
377
378#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
381pub(crate) enum FieldIdent<'a> {
382 Index(usize, Ident),
383 Named(&'a Ident),
384}
385
386impl<'a> ToTokens for FieldIdent<'a> {
387 fn to_tokens(&self, tokens: &mut TokenStream) {
388 match *self {
389 FieldIdent::Index(ind, ..) => syn::Index::from(ind).to_tokens(tokens),
390 FieldIdent::Named(name) => name.to_tokens(tokens),
391 }
392 }
393}
394
395impl<'a> FieldIdent<'a> {
396 fn new_index(index: usize, span: Span) -> Self {
397 let mut buff = ArrayString::<[u8; 16]>::new();
398 let _ = write!(buff, "field_{}", index);
399 FieldIdent::Index(index, Ident::new(&buff, span))
400 }
401}
402