Skip to content

Commit 02b92ec

Browse files
committed
WIP add skip_if macro attribute
1 parent 664714c commit 02b92ec

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

protocol-derive/src/codegen/enums.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub fn read_variant(plan: &plan::Enum)
4747
let discriminator_match_branches = plan.variants.iter().map(|variant| {
4848
let variant_name = &variant.ident;
4949
let discriminator_literal = variant.discriminator_literal();
50-
let initializer = codegen::read_fields(&variant.fields);
50+
let initializer = codegen::read_enum_fields(&variant.fields);
5151

5252
quote! {
5353
#discriminator_literal => {

protocol-derive/src/codegen/mod.rs

+54-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,19 @@ use crate::attr;
66

77
pub mod enums;
88

9-
pub fn read_fields(fields: &syn::Fields)
9+
pub fn read_struct_field(fields: &syn::Fields)
10+
-> TokenStream {
11+
match *fields {
12+
syn::Fields::Named(ref fields_named) => read_named_fields_struct(fields_named),
13+
syn::Fields::Unnamed(ref fields_unnamed) => read_unnamed_fields(fields_unnamed),
14+
syn::Fields::Unit => quote!(),
15+
}
16+
}
17+
18+
pub fn read_enum_fields(fields: &syn::Fields)
1019
-> TokenStream {
1120
match *fields {
12-
syn::Fields::Named(ref fields_named) => read_named_fields(fields_named),
21+
syn::Fields::Named(ref fields_named) => read_named_fields_enum(fields_named),
1322
syn::Fields::Unnamed(ref fields_unnamed) => read_unnamed_fields(fields_unnamed),
1423
syn::Fields::Unit => quote!(),
1524
}
@@ -24,12 +33,39 @@ pub fn write_fields(fields: &syn::Fields)
2433
}
2534
}
2635

36+
pub fn name_fields_declarations(fields: &syn::Fields) -> TokenStream {
37+
if let syn::Fields::Named(ref fields_named) = fields {
38+
let fields_variables: Vec<TokenStream> = fields_named.named.iter().map(|field| {
39+
let field_name = &field.ident;
40+
let field_ty = &field.ty;
41+
// This field may store the length prefix of one or more other field.
42+
let update_hints = update_hints_after_read(field, &fields_named.named);
43+
let update_hints_fixed = update_hint_fixed_length(field, &fields_named.named);
44+
45+
quote! {
46+
#update_hints_fixed
47+
let #field_name: Result<#field_ty, _> = protocol::Parcel::read_field(__io_reader, __settings, &mut __hints);
48+
let res = &#field_name;
49+
#update_hints
50+
__hints.next_field();
51+
}
52+
}).collect();
53+
54+
quote! {
55+
#( #fields_variables)*
56+
}
57+
} else {
58+
quote!()
59+
}
60+
61+
}
62+
2763
/// Generates code that builds a initializes
2864
/// an item with named fields by parsing
2965
/// each of the fields.
3066
///
3167
/// Returns `{ ..field initializers.. }`.
32-
fn read_named_fields(fields_named: &syn::FieldsNamed)
68+
fn read_named_fields_enum(fields_named: &syn::FieldsNamed)
3369
-> TokenStream {
3470
let field_initializers: Vec<_> = fields_named.named.iter().map(|field| {
3571
let field_name = &field.ident;
@@ -52,6 +88,21 @@ fn read_named_fields(fields_named: &syn::FieldsNamed)
5288
quote! { { #( #field_initializers ),* } }
5389
}
5490

91+
/// Generates code that builds a initializes
92+
/// an item with named fields by parsing
93+
/// each of the fields.
94+
///
95+
/// Returns `{ ..field initializers.. }`.
96+
fn read_named_fields_struct(fields_named: &syn::FieldsNamed)
97+
-> TokenStream {
98+
let field_initializers: Vec<_> = fields_named.named.iter().map(|field| {
99+
let field_name = &field.ident;
100+
quote! { #field_name: #field_name? }
101+
}).collect();
102+
103+
quote! { { #( #field_initializers ),* } }
104+
}
105+
55106
fn update_hints_after_read<'a>(field: &'a syn::Field,
56107
fields: impl IntoIterator<Item=&'a syn::Field> + Clone)
57108
-> TokenStream {

protocol-derive/src/lib.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,9 @@ fn build_generics(ast: &syn::DeriveInput) -> (Vec<proc_macro2::TokenStream>, Vec
7373
fn impl_parcel_for_struct(ast: &syn::DeriveInput,
7474
strukt: &syn::DataStruct) -> proc_macro2::TokenStream {
7575
let strukt_name = &ast.ident;
76-
let read_fields = codegen::read_fields(&strukt.fields);
76+
let read_fields = codegen::read_struct_field(&strukt.fields);
7777
let write_fields = codegen::write_fields(&strukt.fields);
78+
let named_field_variables = codegen::name_fields_declarations(&strukt.fields);
7879

7980
impl_trait_for(ast, quote!(protocol::Parcel), quote! {
8081
const TYPE_NAME: &'static str = stringify!(#strukt_name);
@@ -87,7 +88,7 @@ fn impl_parcel_for_struct(ast: &syn::DeriveInput,
8788
// Each type gets its own hints.
8889
let mut __hints = protocol::hint::Hints::default();
8990
__hints.begin_fields();
90-
91+
#named_field_variables
9192
Ok(#strukt_name # read_fields)
9293
}
9394

0 commit comments

Comments
 (0)