mirror of
https://github.com/bytedream/serde-inline-default.git
synced 2025-06-27 18:40:31 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
7130dc8927 | |||
cbd26efdd4 | |||
85b1fbdfcd | |||
cc8120fb4a | |||
b0489edfaf | |||
ba2c2133a5 | |||
6bb8576fa8 |
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: cargo
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde-inline-default"
|
name = "serde-inline-default"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
authors = ["ByteDream"]
|
authors = ["ByteDream"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Serde default values via inline declaration"
|
description = "Serde default values via inline declaration"
|
||||||
@ -18,7 +18,7 @@ doctest = false
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2 = "1.0"
|
proc-macro2 = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0", features = ["full"] }
|
syn = { version = "2.0", features = ["full"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
@ -19,7 +19,7 @@ fn value_default() -> u32 { 42 }
|
|||||||
|
|
||||||
That can get quiet messy if you have many fields with many (different) default values.
|
That can get quiet messy if you have many fields with many (different) default values.
|
||||||
This crate tries to solve this issue by providing the `#[serde_inline_default]` proc macro.
|
This crate tries to solve this issue by providing the `#[serde_inline_default]` proc macro.
|
||||||
With this macro set at the struct level (_before `#[derive(Deserialize)]`/`#[derive(Serialize)]`!_, otherwise it's not working correctly), you can set default values via `#[serde_inline_default(...)]` for your serde fields inline, without creating an extra function.
|
With this macro set at the struct level (_**before `#[derive(Deserialize)]`/`#[derive(Serialize)]`!, otherwise it's not working correctly**_), you can set default values via `#[serde_inline_default(...)]` for your serde fields inline, without creating an extra function.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
#[serde_inline_default]
|
#[serde_inline_default]
|
||||||
|
29
examples/basic.rs
Normal file
29
examples/basic.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use serde::Deserialize;
|
||||||
|
use serde_inline_default::serde_inline_default;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
#[serde_inline_default]
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Basic {
|
||||||
|
// if using `String` you have to call `.to_string()`
|
||||||
|
#[serde_inline_default("0.0.0.0".to_string())]
|
||||||
|
host: String,
|
||||||
|
// works without specifying the integer type at the end of the value (8080u16)
|
||||||
|
#[serde_inline_default(8080)]
|
||||||
|
port: u16,
|
||||||
|
// expressions are working too
|
||||||
|
#[serde_inline_default(serde_json::json!({}))]
|
||||||
|
random_third_party_type: serde_json::Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), serde_json::Error> {
|
||||||
|
// creating a empty json object to use the default value of all fields
|
||||||
|
let json_object = json!({});
|
||||||
|
let basic: Basic = serde_json::from_value(json_object)?;
|
||||||
|
|
||||||
|
assert_eq!(basic.host, "0.0.0.0".to_string());
|
||||||
|
assert_eq!(basic.port, 8080);
|
||||||
|
assert_eq!(basic.random_third_party_type, json!({}));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
39
examples/macro_rules.rs
Normal file
39
examples/macro_rules.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
use serde_json::json;
|
||||||
|
macro_rules! simple_macro {
|
||||||
|
(struct $name:ident { $($field:ident: $type:ty $(= $default:expr)?),*$(,)? }) => {
|
||||||
|
#[serde_inline_default::serde_inline_default]
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
struct $name {
|
||||||
|
$(
|
||||||
|
$(
|
||||||
|
#[serde_inline_default($default)]
|
||||||
|
)?
|
||||||
|
$field: $type
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), serde_json::Error> {
|
||||||
|
// `username` and `password` must be set when deserializing as no default value is defined for
|
||||||
|
// them. `secret` not as we're defining a default value for it
|
||||||
|
simple_macro! {
|
||||||
|
struct Example {
|
||||||
|
username: String,
|
||||||
|
password: String,
|
||||||
|
secret: String = "verysecretsecret".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let json_object = json!({
|
||||||
|
"username": "testuser",
|
||||||
|
"password": "testpassword"
|
||||||
|
});
|
||||||
|
|
||||||
|
let example: Example = serde_json::from_value(json_object)?;
|
||||||
|
assert_eq!(example.username, "testuser");
|
||||||
|
assert_eq!(example.password, "testpassword");
|
||||||
|
assert_eq!(example.secret, "verysecretsecret");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -7,12 +7,11 @@ pub(crate) fn expand_struct(mut item: ItemStruct) -> proc_macro::TokenStream {
|
|||||||
|
|
||||||
for (i, field) in item.fields.iter_mut().enumerate() {
|
for (i, field) in item.fields.iter_mut().enumerate() {
|
||||||
for (j, attr) in field.attrs.iter_mut().enumerate() {
|
for (j, attr) in field.attrs.iter_mut().enumerate() {
|
||||||
if !attr.path.is_ident("serde_inline_default") {
|
if !attr.path().is_ident("serde_inline_default") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let _default_str = attr.tokens.to_string();
|
let default: TokenStream = attr.parse_args().unwrap();
|
||||||
let default: TokenStream = _default_str[1.._default_str.len() - 1].parse().unwrap();
|
|
||||||
|
|
||||||
// we check here if a function with the exact same return value already exists. if so,
|
// we check here if a function with the exact same return value already exists. if so,
|
||||||
// this function gets used.
|
// this function gets used.
|
||||||
|
@ -17,6 +17,8 @@ fn test_serde_inline_default() {
|
|||||||
inline: u32,
|
inline: u32,
|
||||||
#[serde_inline_default(-1337)]
|
#[serde_inline_default(-1337)]
|
||||||
inline_negative: i32,
|
inline_negative: i32,
|
||||||
|
#[serde_inline_default("string".to_string())]
|
||||||
|
string: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
let test: Test = serde_json::from_value(json!({})).unwrap();
|
let test: Test = serde_json::from_value(json!({})).unwrap();
|
||||||
@ -24,4 +26,5 @@ fn test_serde_inline_default() {
|
|||||||
assert_eq!(test.native, 69);
|
assert_eq!(test.native, 69);
|
||||||
assert_eq!(test.inline, 420);
|
assert_eq!(test.inline, 420);
|
||||||
assert_eq!(test.inline_negative, -1337);
|
assert_eq!(test.inline_negative, -1337);
|
||||||
|
assert_eq!(test.string, "string".to_string());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user