4 个版本
0.2.2 | 2024年2月1日 |
---|---|
0.2.1 | 2024年1月16日 |
0.2.0 | 2024年1月15日 |
0.1.0 | 2024年1月10日 |
#964 在 编码
每月下载量 877
用于 zika
16KB
94 行
serde_default_utils
概览
这是一个简化函数集,用于在 serde 中处理默认值,基于 const 泛型参数。深受 serde 默认值问题讨论的启发,但主要是 这个
致谢
- JohnTheCoolingFan 提出了这个解决方案,我只是将其作为 crate 和宏的形式提供,以帮助生成任何 const 泛型类型的另一个 const 泛型函数。
- bytedream 制作了一个更强大的版本,尽管我仍然认为 const 泛型方法更具可读性,但我必须承认,对于字符串来说,它的性能更优越,因此将其包含在功能中。
示例
use serde_default_utils::*;
use serde::{Deserialize, Serialize};
const JSON: &str =
r#"{
"yes_or_no":false,
"max":60,
"delta":-77,
"delimeter":"☀",
"motto":"I matter"
}"#;
const INLINE_JSON: &str =
r#"{
"inline_motto":"I matter even more",
"slice":["I", "matter", "even", "more"],
"slice_u64":[9000, 8000, 10000, 7000]
}"#;
const EMPTY_JSON: &str = r#"{}"#;
const MAX: u32 = 7;
serde_default!(motto, "You matter");
#[derive(Serialize, Deserialize, Default)]
struct Config {
#[serde(default = "default_bool::<true>")]
yes_or_no: bool,
#[serde(default = "default_i16::<-3>")]
delta: i16,
// you can even use consts right here
#[serde(default = "default_u32::<MAX>")]
max: u32,
#[serde(default = "default_char::<'☀'>")]
delimeter: char,
#[serde(default = "default_motto")]
motto: &'static str,
}
#[cfg(feature = "inline")]
#[serde_inline_default]
#[derive(Serialize, Deserialize, Default)]
struct InlineConfig {
#[serde_inline_default("You matter even more".to_string())]
inline_motto: String,
#[serde_inline_default(vec!["You", "matter", "even", "more"])]
slice: Vec<&'static str>,
#[serde_inline_default(vec![98712, 12346, 129389, 102937])]
slice_u64: Vec<u64>,
}
fn main() {
// existing json fields are not changed
let config: Config = serde_json::from_str(JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"yes_or_no":false,"delta":-77,"max":60,"delimeter":"☀","motto":"I matter"}"#, &s);
// if the field is not present - it is substituted with defaults
let config: Config = serde_json::from_str(EMPTY_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"yes_or_no":true,"delta":-3,"max":7,"delimeter":"☀","motto":"You matter"}"#, &s);
// the default impl is just calling underlying type defaults unless you have a custom impl Default
let config = Config::default();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"yes_or_no":false,"delta":0,"max":0,"delimeter":"\u0000","motto":""}"#, &s);
// Inline
#[cfg(feature = "inline")]
{
// existing json fields are not changed
let config: InlineConfig = serde_json::from_str(INLINE_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"inline_motto":"I matter even more","slice":["I","matter","even","more"],"slice_u64":[9000,8000,10000,7000]}"#, &s);
// if the field is not present - it is substituted with defaults
let config: InlineConfig = serde_json::from_str(EMPTY_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"inline_motto":"You matter even more","slice":["You","matter","even","more"],"slice_u64":[98712,12346,129389,102937]}"#, &s);
// the default impl is just calling underlying type defaults unless you have a custom impl Default
let config = Config::default();
let s = serde_json::to_string(&config).unwrap();
assert_eq!(r#"{"inline_motto":"","slice":[],"slice_u64":[]}"#, &s);
}
}
许可证:MIT OR Apache-2.0
依赖项
~110KB