Skip to content

Commit

Permalink
serde_ron: skip attribute; serde_ron, serde_json: tests for skip, def…
Browse files Browse the repository at this point in the history
…ault

Also tests and added attributes to feature table
  • Loading branch information
birhburh authored and knickish committed Aug 26, 2024
1 parent 66e9f59 commit 418cbb9
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 58 deletions.
47 changes: 25 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,39 @@ For more examples take a look at [tests](/tests)

## Features support matrix:

| Feature | json | bin | ron | toml |
| ---------------------------------------------- | ------ | ----- | ------ | ----- |
| serialization | yes | yes | yes | no |
| deserialization | yes | yes | yes | no |
| container: Struct | yes | yes | yes | no |
| container: Tuple Struct | no | yes | yes | no |
| container: Enum | yes | yes | yes | no |
| field: `std::collections::HashMap` | yes | yes | yes | no |
| field: `std::vec::Vec` | yes | yes | yes | no |
| field: `Option` | yes | yes | yes | no |
| field: `i*`/`f*`/`String`/`T: De*/Ser*` | yes | yes | yes | no |
| field attribute: `#[nserde(default)]` | yes | no | yes | no |
| field attribute: `#[nserde(rename = "")]` | yes | yes | yes | no |
| field attribute: `#[nserde(proxy = "")]` | no | yes | no | no |
| container attribute: `#[nserde(default)]` | yes | no | yes | no |
| container attribute: `#[nserde(rename = "")]` | yes | yes | yes | no |
| container attribute: `#[nserde(proxy = "")]` | yes | yes | no | no |
| container attribute: `#[nserde(transparent)]` | yes | no | no | no |
| Feature | json | bin | ron | toml |
| --------------------------------------------------- | ------ | ----- | ------ | ----- |
| serialization | yes | yes | yes | no |
| deserialization | yes | yes | yes | no |
| container: Struct | yes | yes | yes | no |
| container: Tuple Struct | no | yes | yes | no |
| container: Enum | yes | yes | yes | no |
| field: `std::collections::HashMap` | yes | yes | yes | no |
| field: `std::vec::Vec` | yes | yes | yes | no |
| field: `Option` | yes | yes | yes | no |
| field: `i*`/`f*`/`String`/`T: De*/Ser*` | yes | yes | yes | no |
| field attribute: `#[nserde(default)]` | yes | no | yes | no |
| field attribute: `#[nserde(rename = "")]` | yes | yes | yes | no |
| field attribute: `#[nserde(proxy = "")]` | no | yes | no | no |
| container attribute: `#[nserde(default)]` | yes | no | yes | no |
| container attribute: `#[nserde(default = "")]` | yes | no | yes | no |
| container attribute: `#[nserde(default_with = "")]` | yes | no | yes | no |
| container attribute: `#[nserde(skip)]` | yes | no | yes | no |
| container attribute: `#[nserde(rename = "")]` | yes | yes | yes | no |
| container attribute: `#[nserde(proxy = "")]` | yes | yes | no | no |
| container attribute: `#[nserde(transparent)]` | yes | no | no | no |

## Crate features:

All features are enabled by default. To enable only specific formats, import nanoserde using
All features are enabled by default. To enable only specific formats, import nanoserde using
```toml
nanoserde = { version = "*", default-features = false, features = ["std", "{format feature name}"] }
```
in your `Cargo.toml` and add one or more of the following crate features:

| Format | Feature Name |
| Format | Feature Name |
| ----------| -------------- |
| Binary | `binary` |
| JSON | `json` |
| Binary | `binary` |
| JSON | `json` |
| RON | `ron` |
| TOML | `toml` |
79 changes: 44 additions & 35 deletions derive/src/serde_ron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ pub fn derive_ser_ron_struct(struct_: &Struct) -> TokenStream {
let struct_fieldname = field.field_name.clone().unwrap();
let ron_fieldname =
shared::attrs_rename(&field.attributes).unwrap_or_else(|| struct_fieldname.clone());
let skip = shared::attrs_skip(&field.attributes);
if skip {
continue;
}
if field.ty.base() == "Option" {
l!(
s,
Expand Down Expand Up @@ -156,42 +160,47 @@ pub fn derive_de_ron_named(
};
let ron_fieldname =
shared::attrs_rename(&field.attributes).unwrap_or(struct_fieldname.clone());

if field.ty.base() == "Option" {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
{}
}}
}}",
localvar,
default_val.unwrap_or_else(|| String::from("None"))
));
} else if container_attr_default || default_val.is_some() {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
{}
}}
}}",
localvar,
default_val.unwrap_or_else(|| String::from("Default::default()"))
));
let skip = crate::shared::attrs_skip(&field.attributes);

if skip == false {
if field.ty.base() == "Option" {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
{}
}}
}}",
localvar,
default_val.unwrap_or_else(|| String::from("None"))
));
} else if container_attr_default || default_val.is_some() {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
{}
}}
}}",
localvar,
default_val.unwrap_or_else(|| String::from("Default::default()"))
));
} else {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
return Err(s.err_nf(\"{}\"))
}}
}}",
localvar, struct_fieldname
));
}
} else {
unwraps.push(format!(
"{{
if let Some(t) = {} {{
t
}} else {{
return Err(s.err_nf(\"{}\"))
}}
}}",
localvar, struct_fieldname
));
unwraps.push(default_val.unwrap_or_else(|| String::from("Default::default()")));
}

struct_field_names.push(struct_fieldname);
Expand Down
2 changes: 1 addition & 1 deletion derive/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub fn attrs_transparent(attributes: &[crate::parse::Attribute]) -> bool {
.any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "transparent")
}

#[cfg(feature = "json")]
#[cfg(any(feature = "json", feature = "ron"))]
pub fn attrs_skip(attributes: &[crate::parse::Attribute]) -> bool {
attributes
.iter()
Expand Down
65 changes: 65 additions & 0 deletions tests/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,71 @@ fn de_field_default() {
assert_eq!(test.foo2.x, 3);
}

#[test]
fn de_ser_field_skip() {
#[derive(DeJson, SerJson)]
struct Foo {
x: i32,
}
impl Default for Foo {
fn default() -> Foo {
Foo { x: 23 }
}
}

fn h_default() -> Option<String> {
Some("h not empty".into())
}

#[derive(DeJson, SerJson)]
pub struct Test {
a: i32,
#[nserde(skip)]
foo: Foo,
foo2: Foo,
#[nserde(skip, default = "4.0")]
b: f32,
#[nserde(skip, default)]
c: f32,
#[nserde(skip)]
d: i32,
#[nserde(skip)]
e: String,
#[nserde(skip)]
f: Foo,
#[nserde(skip)]
g: Option<i32>,
#[nserde(skip, default_with = "h_default")]
h: Option<String>,
}

let json = r#"{
"a": 1,
"c": 3.0,
"h": "h not empty",
"foo2": { "x": 3 }
}"#;

let mut test: Test = DeJson::deserialize_json(json).unwrap();
assert_eq!(test.a, 1);
assert_eq!(test.b, 4.0);
assert_eq!(test.c, 0.0);
assert_eq!(test.d, 0);
assert_eq!(test.e, "");
assert_eq!(test.f.x, 23);
assert_eq!(test.g, None);
assert_eq!(test.h, Some("h not empty".into()));
assert_eq!(test.foo.x, 23);
assert_eq!(test.foo2.x, 3);

test.e = "e not empty".into();
test.g = Some(2);

let ser_json = r#"{"a":1,"foo2":{"x":3}}"#;
let serialized = SerJson::serialize_json(&test);
assert_eq!(serialized, ser_json);
}

#[test]
fn doctests() {
/// This is test
Expand Down
55 changes: 55 additions & 0 deletions tests/ron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,18 @@ fn de_field_default() {
Foo { x: 23 }
}
}
fn foo3_default() -> Foo {
Foo { x: 15 }
}

#[derive(DeRon)]
pub struct Test {
a: i32,
#[nserde(default)]
foo: Foo,
foo2: Foo,
#[nserde(default_with = "foo3_default")]
foo3: Foo,
b: f32,
}

Expand All @@ -112,6 +117,56 @@ fn de_field_default() {
assert_eq!(test.b, 2.);
assert_eq!(test.foo.x, 23);
assert_eq!(test.foo2.x, 3);
assert_eq!(test.foo3.x, 15);
}

#[test]
fn de_ser_field_skip() {
#[derive(DeRon, SerRon, PartialEq, Debug)]
struct Foo {
x: i32,
}
impl Default for Foo {
fn default() -> Foo {
Foo { x: 23 }
}
}
fn foo3_default() -> Foo {
Foo { x: 15 }
}

#[derive(DeRon, SerRon, PartialEq, Debug)]

Check warning on line 138 in tests/ron.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (ron)

this function depends on never type fallback being `()`

Check warning on line 138 in tests/ron.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

this function depends on never type fallback being `()`

Check warning on line 138 in tests/ron.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

this function depends on never type fallback being `()`
pub struct Test {
a: i32,
#[nserde(skip)]
foo: Foo,
foo2: Foo,
#[nserde(skip, default_with = "foo3_default")]
foo3: Foo,
b: f32,
#[nserde(skip)]
c: Option<i32>,
}

let ron = r#"(
a: 1,
b: 2.,
foo2: (x: 3)
)"#;

let mut test: Test = DeRon::deserialize_ron(ron).unwrap();
assert_eq!(test.a, 1);
assert_eq!(test.b, 2.);
assert_eq!(test.foo.x, 23);
assert_eq!(test.foo2.x, 3);
assert_eq!(test.foo3.x, 15);

test.c = Some(2);
let serialized = SerRon::serialize_ron(&test);

let test: Test = DeRon::deserialize_ron(ron).unwrap();
let deserialized: Test = DeRon::deserialize_ron(&serialized).unwrap();
assert_eq!(deserialized, test);
}

#[test]
Expand Down

0 comments on commit 418cbb9

Please sign in to comment.