Skip to content

Commit 22f1afa

Browse files
committed
Make length prefix usable more that once
1 parent f721ea3 commit 22f1afa

File tree

6 files changed

+47
-54
lines changed

6 files changed

+47
-54
lines changed

examples/get_enum_discriminant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pub struct Goodbye {
1818
reason: String,
1919
}
2020

21-
#[protocol(discriminant = "integer")]
2221
#[derive(Protocol, Clone, Debug, PartialEq)]
22+
#[protocol(discriminant = "integer")]
2323
#[repr(u16)]
2424
pub enum PacketKind {
2525
#[protocol(discriminator(0x00))]

protocol-derive/src/codegen/mod.rs

+43-43
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
pub mod enums;
2-
3-
use crate::attr;
4-
use proc_macro2::{TokenStream, Ident};
1+
use proc_macro2::TokenStream;
52
use syn;
63
use syn::Field;
74

5+
use crate::attr;
6+
7+
pub mod enums;
8+
89
pub fn read_fields(fields: &syn::Fields)
9-
-> TokenStream {
10+
-> TokenStream {
1011
match *fields {
1112
syn::Fields::Named(ref fields_named) => read_named_fields(fields_named),
1213
syn::Fields::Unnamed(ref fields_unnamed) => read_unnamed_fields(fields_unnamed),
@@ -15,7 +16,7 @@ pub fn read_fields(fields: &syn::Fields)
1516
}
1617

1718
pub fn write_fields(fields: &syn::Fields)
18-
-> TokenStream {
19+
-> TokenStream {
1920
match *fields {
2021
syn::Fields::Named(ref fields_named) => write_named_fields(fields_named),
2122
syn::Fields::Unnamed(ref fields_unnamed) => write_unnamed_fields(fields_unnamed),
@@ -32,7 +33,6 @@ fn read_named_fields(fields_named: &syn::FieldsNamed)
3233
-> TokenStream {
3334
let field_initializers: Vec<_> = fields_named.named.iter().map(|field| {
3435
let field_name = &field.ident;
35-
println!("READING NAMED FIELD {:?}", field_name);
3636
let field_ty = &field.ty;
3737
// This field may store the length prefix of one or more other field.
3838
let update_hints = update_hints_after_read(field, &fields_named.named);
@@ -55,29 +55,30 @@ fn read_named_fields(fields_named: &syn::FieldsNamed)
5555
fn update_hints_after_read<'a>(field: &'a syn::Field,
5656
fields: impl IntoIterator<Item=&'a syn::Field> + Clone)
5757
-> TokenStream {
58-
if let Some((length_prefix_of, kind, prefix_subfield_names)) = length_prefix_of(field, fields.clone()) {
58+
let hint_setters = length_prefix_of(field, fields.clone()).iter().map(|(length_prefix_of, kind, prefix_subfield_names)| {
5959
let kind = kind.path_expr();
60-
let field_name = &field.ident.clone().map(|i| i.to_string());
61-
let debug = (field_name, &length_prefix_of, &kind, &prefix_subfield_names);
62-
println!("About to set hints for {:?}, of_index : {:?}, subfield names {:?}", field_name, &length_prefix_of, &prefix_subfield_names);
60+
quote! {
61+
__hints.set_field_length(#length_prefix_of,
62+
(parcel #(.#prefix_subfield_names)* ).clone() as usize,
63+
#kind);
64+
}
65+
}).collect::<Vec<TokenStream>>();
66+
67+
if hint_setters.is_empty() {
68+
quote! {}
69+
} else {
6370
quote! {
6471
if let Ok(parcel) = res.as_ref() {
65-
println!(" setting {:?} fields hint {:?}, {:?}, {:?}",#field_name, #length_prefix_of, (parcel #(.#prefix_subfield_names)* ).clone() as usize, #kind);
66-
__hints.set_field_length(#length_prefix_of,
67-
(parcel #(.#prefix_subfield_names)* ).clone() as usize,
68-
#kind);
72+
#(#hint_setters);*
6973
}
7074
}
71-
}else {
72-
quote! { }
7375
}
7476
}
7577

7678
fn update_hint_fixed_length<'a>(field: &'a syn::Field,
7779
fields: impl IntoIterator<Item=&'a syn::Field> + Clone)
7880
-> TokenStream {
79-
80-
if let Some(attr::Protocol::FixedLength(length)) = attr::protocol(&field.attrs) {
81+
if let Some(attr::Protocol::FixedLength(length)) = attr::protocol(&field.attrs) {
8182
let position = fields.clone().into_iter().position(|f| f == field).unwrap();
8283

8384
quote! {
@@ -90,22 +91,26 @@ fn update_hint_fixed_length<'a>(field: &'a syn::Field,
9091

9192
fn update_hints_after_write<'a>(field: &'a syn::Field,
9293
fields: impl IntoIterator<Item=&'a syn::Field> + Clone)
93-
-> TokenStream {
94-
if let Some((length_prefix_of, kind, prefix_subfield_names)) = length_prefix_of(field, fields.clone()) {
94+
-> TokenStream {
95+
let hint_setters = length_prefix_of(field, fields.clone()).iter().map(|(length_prefix_of, kind, prefix_subfield_names)| {
9596
let field_name = &field.ident;
9697
let kind = kind.path_expr();
97-
let debug = (&field.ident.clone().map(|i| i.to_string()), &length_prefix_of, &kind, &prefix_subfield_names);
98-
println!("About setting hints for {:?}", debug);
98+
9999
quote! {
100-
println!(" WRITE setting {:?} fields hint {:?}, {:?}",self.#field_name #(.#prefix_subfield_names)*, #length_prefix_of, #kind);
101-
if let Ok(()) = res {
102100
__hints.set_field_length(#length_prefix_of,
103101
(self.#field_name #(.#prefix_subfield_names)* ).clone() as usize,
104102
#kind);
105-
}
106103
}
104+
}).collect::<Vec<TokenStream>>();
105+
106+
if hint_setters.is_empty() {
107+
quote! {}
107108
} else {
108-
quote! { }
109+
quote! {
110+
if let Ok(()) = res {
111+
#(#hint_setters);*
112+
}
113+
}
109114
}
110115
}
111116

@@ -117,37 +122,33 @@ fn update_hints_after_write<'a>(field: &'a syn::Field,
117122
/// Returns the field index of the field whose length is specified.
118123
fn length_prefix_of<'a>(field: &'a syn::Field,
119124
fields: impl IntoIterator<Item=&'a syn::Field> + Clone)
120-
-> Option<Vec<(usize, attr::LengthPrefixKind, Vec<syn::Ident>)>> {
125+
-> Vec<(usize, attr::LengthPrefixKind, Vec<syn::Ident>)> {
121126
let potential_prefix = field.ident.as_ref();
122127

123-
let prefixes_of: Vec<&Ident> = fields.clone().into_iter().filter(|potential_prefix_of| {
128+
let prefixes_of: Vec<&'a Field> = fields.clone().into_iter().filter(|potential_prefix_of| {
124129
match attr::protocol(&potential_prefix_of.attrs) {
125130
Some(attr::Protocol::LengthPrefix { ref prefix_field_name, .. }) => {
126131
if !fields.clone().into_iter().any(|f| f.ident.as_ref() == Some(prefix_field_name)) {
127132
panic!("length prefix is invalid: there is no sibling field named '{}", prefix_field_name);
128133
}
129134

130135
potential_prefix == Some(prefix_field_name)
131-
},
136+
}
132137
_ => false,
133138
}
134139
}).collect();
135140

136141

137142
prefixes_of.iter()
138143
.map(|prefix_of| {
139-
if let Some(prefix_of) = prefix_of {
140-
let prefix_of_index = fields.clone().into_iter().position(|f| f == prefix_of).unwrap();
141-
match attr::protocol(&prefix_of.attrs).unwrap() {
142-
attr::Protocol::LengthPrefix { kind, prefix_subfield_names, .. } => {
143-
Some((prefix_of_index, kind.clone(), prefix_subfield_names))
144-
},
145-
_ => unreachable!(),
144+
let prefix_of_index = fields.clone().into_iter().position(|f| &f == prefix_of).unwrap();
145+
match attr::protocol(&prefix_of.attrs).unwrap() {
146+
attr::Protocol::LengthPrefix { kind, prefix_subfield_names, .. } => {
147+
(prefix_of_index, kind.clone(), prefix_subfield_names)
146148
}
147-
} else {
148-
None
149+
_ => unreachable!(),
149150
}
150-
}).flatten().collect()
151+
}).collect()
151152
}
152153

153154
fn write_named_fields(fields_named: &syn::FieldsNamed)
@@ -158,7 +159,6 @@ fn write_named_fields(fields_named: &syn::FieldsNamed)
158159
let update_hints = update_hints_after_write(field, &fields_named.named);
159160
let update_hints_fixed = update_hint_fixed_length(field, &fields_named.named);
160161

161-
println!("WRITE Hints after ");
162162
quote! {
163163
{
164164
#update_hints_fixed
@@ -174,7 +174,7 @@ fn write_named_fields(fields_named: &syn::FieldsNamed)
174174
}
175175

176176
fn read_unnamed_fields(fields_unnamed: &syn::FieldsUnnamed)
177-
-> TokenStream {
177+
-> TokenStream {
178178
let field_initializers: Vec<_> = fields_unnamed.unnamed.iter().map(|field| {
179179
let field_ty = &field.ty;
180180

@@ -191,7 +191,7 @@ fn read_unnamed_fields(fields_unnamed: &syn::FieldsUnnamed)
191191
}
192192

193193
fn write_unnamed_fields(fields_unnamed: &syn::FieldsUnnamed)
194-
-> TokenStream {
194+
-> TokenStream {
195195
let field_indices = (0..fields_unnamed.unnamed.len()).into_iter().map(syn::Index::from);
196196

197197
let field_writers: Vec<_> = field_indices.map(|field_index| {

protocol-derive/src/lib.rs

-3
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,7 @@ 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-
println!("Reading struct fields {:?}", &strukt.fields);
7776
let read_fields = codegen::read_fields(&strukt.fields);
78-
println!("{}", read_fields);
7977
let write_fields = codegen::write_fields(&strukt.fields);
8078

8179
impl_trait_for(ast, quote!(protocol::Parcel), quote! {
@@ -86,7 +84,6 @@ fn impl_parcel_for_struct(ast: &syn::DeriveInput,
8684
__settings: &protocol::Settings,
8785
_: &mut protocol::hint::Hints)
8886
-> Result<Self, protocol::Error> {
89-
println!("reading fields with default Hints");
9087
// Each type gets its own hints.
9188
let mut __hints = protocol::hint::Hints::default();
9289
__hints.begin_fields();

protocol/src/hint.rs

-3
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,12 @@ mod protocol_derive_helpers {
5656
// Sets hints indicating a new set of fields are beginning.
5757
#[doc(hidden)]
5858
pub fn begin_fields(&mut self) {
59-
println!("Starting from field 0");
6059
self.current_field_index = Some(0);
6160
}
6261

6362
// Updates the hints to indicate a field was just read.
6463
#[doc(hidden)]
6564
pub fn next_field(&mut self) {
66-
println!("Current field +1");
6765
*self.current_field_index.as_mut()
6866
.expect("cannot increment next field when not in a struct")+= 1;
6967
}
@@ -74,7 +72,6 @@ mod protocol_derive_helpers {
7472
field_index: FieldIndex,
7573
length: usize,
7674
kind: LengthPrefixKind) {
77-
println!("Set field length {:?}", (field_index, length, kind));
7875
self.known_field_lengths.insert(field_index, FieldLength { kind, length });
7976
}
8077
}

protocol/src/util.rs

-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ pub fn read_list_ext<S,T>(read: &mut dyn Read,
7575
-> Result<Vec<T>, Error>
7676
where S: Integer,
7777
T: Parcel {
78-
println!("About to read list ext with prefix and hint {:?}", hints);
7978
match hints.current_field_length() {
8079
Some(length) => {
8180
match length.kind {

tests/src/length_prefix.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ fn can_read_twice_the_same_prefix_length() {
103103
0, 0, 0, 1, // 1
104104
0, 0, 0, 2, // 2
105105
0, 0, 0, 3, // 3
106-
0, 0, 0, 1, // 4
107-
0, 0, 0, 2, // 5
108-
0, 0, 0, 3 // 6
106+
0, 0, 0, 4, // 4
107+
0, 0, 0, 5, // 5
108+
0, 0, 0, 6 // 6
109109
],
110110
&Settings::default()).unwrap());
111111
}

0 commit comments

Comments
 (0)