Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Do not skip null values in pairlists #166

Merged
merged 5 commits into from
Jan 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions general/derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ fn derive_metastructure(s: synstructure::Structure<'_>, t: Trait) -> TokenStream
}

let mut is_tuple_struct = false;

for (index, bi) in variant.bindings().iter().enumerate() {
let field_attrs = parse_field_attributes(index, &bi.ast(), &mut is_tuple_struct);
let field_attrs_name = Ident::new(&format!("__field_attrs_{}", index), Span::call_site());
Expand Down Expand Up @@ -625,10 +626,7 @@ fn derive_metastructure(s: synstructure::Structure<'_>, t: Trait) -> TokenStream
}

let ast = s.ast();
let expectation = LitStr::new(
&format!("expected {}", ast.ident.to_string().to_lowercase()),
Span::call_site(),
);
let expectation = LitStr::new(&ast.ident.to_string().to_lowercase(), Span::call_site());
let mut variant = variant.clone();
for binding in variant.bindings_mut() {
binding.style = synstructure::BindStyle::Move;
Expand Down Expand Up @@ -661,12 +659,19 @@ fn derive_metastructure(s: synstructure::Structure<'_>, t: Trait) -> TokenStream
}
}),
Trait::From => {
let bindings_count = variant.bindings().len();
let valid_match_arm = if is_tuple_struct {
quote! {
crate::types::Annotated(Some(crate::types::Value::Array(mut __arr)), __meta) => {
let __arr = __arr.into_iter();
#from_value_body;
crate::types::Annotated(Some(#to_structure_assemble_pat), __meta)
crate::types::Annotated(Some(crate::types::Value::Array(mut __arr)), mut __meta) => {
if __arr.len() != #bindings_count {
__meta.add_error(Error::expected(concat!("a ", stringify!(#bindings_count), "-tuple")));
__meta.set_original_value(Some(__arr));
Annotated(None, __meta)
} else {
let mut __arr = __arr.into_iter();
#from_value_body;
crate::types::Annotated(Some(#to_structure_assemble_pat), __meta)
}
}
}
} else {
Expand Down Expand Up @@ -1010,7 +1015,7 @@ impl SkipSerialization {

impl Default for SkipSerialization {
fn default() -> SkipSerialization {
SkipSerialization::Null(true)
SkipSerialization::Never
}
}

Expand Down Expand Up @@ -1041,6 +1046,9 @@ fn parse_field_attributes(
}

let mut rv = FieldAttrs::default();
if !*is_tuple_struct {
rv.skip_serialization = SkipSerialization::Null(false);
}
rv.field_name = bi_ast
.ident
.as_ref()
Expand Down
14 changes: 12 additions & 2 deletions general/src/protocol/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ fn test_cookies_parsing() {

#[test]
fn test_cookies_array() {
let json = r#"[["foo", "bar"], ["invalid", 42]]"#;
let input = r#"{"cookies":[["foo","bar"],["invalid", 42],["none",null]]}"#;
let output = r#"{"cookies":[["foo","bar"],["invalid",null],["none",null]],"_meta":{"cookies":{"1":{"1":{"":{"err":[["invalid_data",{"reason":"expected a string"}]],"val":42}}}}}}"#;

let mut map = Vec::new();
map.push(Annotated::new((
Expand All @@ -650,9 +651,18 @@ fn test_cookies_array() {
Annotated::new("invalid".to_string()),
Annotated::from_error(Error::expected("a string"), Some(Value::U64(42))),
)));
map.push(Annotated::new((
Annotated::new("none".to_string()),
Annotated::empty(),
)));

let cookies = Annotated::new(Cookies(PairList(map)));
assert_eq_dbg!(cookies, Annotated::from_json(json).unwrap());
let request = Annotated::new(Request {
cookies,
..Default::default()
});
assert_eq_dbg!(request, Annotated::from_json(input).unwrap());
assert_eq_dbg!(request.to_json().unwrap(), output);
}

#[test]
Expand Down
76 changes: 68 additions & 8 deletions general/src/protocol/tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,15 @@ fn test_tags_from_object() {
"blah": "blub",
"bool": true,
"foo bar": "baz",
"non string": 42
"non string": 42,
"bam": null
}"#;

let mut arr = Array::new();
arr.push(Annotated::new(TagEntry(
Annotated::new("bam".to_string()),
Annotated::empty(),
)));
arr.push(Annotated::new(TagEntry(
Annotated::new("blah".to_string()),
Annotated::new("blub".to_string()),
Expand All @@ -97,12 +102,57 @@ fn test_tags_from_object() {

#[test]
fn test_tags_from_array() {
let json = r#"[
["bool", true],
["foo bar", "baz"],
[23, 42],
["blah", "blub"]
]"#;
use crate::protocol::Event;

let input = r#"{
"tags": [
[
"bool",
true
],
[
"foo bar",
"baz"
],
[
23,
42
],
[
"blah",
"blub"
],
[
"bam",
null
]
]
}"#;

let output = r#"{
"tags": [
[
"bool",
"True"
],
[
"foo-bar",
"baz"
],
[
"23",
"42"
],
[
"blah",
"blub"
],
[
"bam",
null
]
]
}"#;

let mut arr = Array::new();
arr.push(Annotated::new(TagEntry(
Expand All @@ -121,7 +171,17 @@ fn test_tags_from_array() {
Annotated::new("blah".to_string()),
Annotated::new("blub".to_string()),
)));
arr.push(Annotated::new(TagEntry(
Annotated::new("bam".to_string()),
Annotated::empty(),
)));

let tags = Annotated::new(Tags(arr.into()));
assert_eq_dbg!(tags, Annotated::from_json(json).unwrap());
let event = Annotated::new(Event {
tags,
..Default::default()
});

assert_eq_dbg!(event, Annotated::from_json(input).unwrap());
assert_eq_str!(event.to_json_pretty().unwrap(), output);
}