#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "inline")]
pub use serde_inline_default::serde_inline_default;
#[macro_export]
macro_rules! serde_default {
($kind:ty) => {
::paste::paste! {
pub const fn [<default_$kind:lower>]<const V: $kind>() -> $kind {
V
}
}
};
($name:ident,$text:literal) => {
::paste::paste! {
pub const fn [<default_$name:lower>]() -> &'static ::core::primitive::str {
$text
}
}
};
($name:ident, &[ $($value:expr),* $(,)? ]) => {
::paste::paste! {
pub const fn [<default_$name:lower>]() -> &'static [::core::primitive::u8] {
&[$($value,)*]
}
}
};
}
serde_default!(bool);
serde_default!(char);
serde_default!(usize);
serde_default!(u8);
serde_default!(u16);
serde_default!(u32);
serde_default!(u64);
serde_default!(u128);
serde_default!(isize);
serde_default!(i8);
serde_default!(i16);
serde_default!(i32);
serde_default!(i64);
serde_default!(i128);
#[cfg(test)]
mod tests {
use super::*;
use expect_test::expect;
use serde::{Deserialize, Serialize};
#[cfg(feature = "inline")]
use serde_inline_default::serde_inline_default;
serde_default!(hey, "You matter");
#[derive(Serialize, Deserialize, Default)]
struct Config {
#[serde(default = "default_bool::<true>")]
yes_or_no: bool,
#[serde(default = "default_i32::<-3>")]
delta: i32,
#[serde(default = "default_u32::<7>")]
max: u32,
#[serde(default = "default_char::<'☀'>")]
delimeter: char,
#[serde(default = "default_hey")]
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".into(), "matter".into(), "even".into(), "more".into()])]
slice: Vec<String>,
#[serde_inline_default(vec![98712, 12346, 129389, 102937])]
slice_u64: Vec<u64>,
}
const JSON: &str = r#"{
"yes_or_no":false,
"max":60,
"delta":-77,
"delimeter":"☀",
"motto":"I matter"
}"#;
#[cfg(feature = "inline")]
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#"{}"#;
#[test]
fn deserialization_works() {
let config: Config = serde_json::from_str(JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
expect![[r#"{"yes_or_no":false,"delta":-77,"max":60,"delimeter":"☀","motto":"I matter"}"#]]
.assert_eq(&s);
let config: Config = serde_json::from_str(EMPTY_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
expect![[r#"{"yes_or_no":true,"delta":-3,"max":7,"delimeter":"☀","motto":"You matter"}"#]]
.assert_eq(&s);
let config = Config::default();
let s = serde_json::to_string(&config).unwrap();
expect![[r#"{"yes_or_no":false,"delta":0,"max":0,"delimeter":"\u0000","motto":""}"#]]
.assert_eq(&s);
#[cfg(feature = "inline")]
{
let config: InlineConfig = serde_json::from_str(INLINE_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
expect![[r#"{"inline_motto":"I matter even more","slice":["I","matter","even","more"],"slice_u64":[9000,8000,10000,7000]}"#]]
.assert_eq(&s);
let config: InlineConfig = serde_json::from_str(EMPTY_JSON).unwrap();
let s = serde_json::to_string(&config).unwrap();
expect![[
r#"{"inline_motto":"You matter even more","slice":["You","matter","even","more"],"slice_u64":[98712,12346,129389,102937]}"#
]].assert_eq(&s);
let config = InlineConfig::default();
let s = serde_json::to_string(&config).unwrap();
expect![[r#"{"inline_motto":"","slice":[],"slice_u64":[]}"#]].assert_eq(&s);
}
}
}