risingwave_common/config/
none_as_empty_string.rs1use serde::de::Error as _;
25use serde::{Deserialize, Deserializer, Serialize, Serializer};
26
27pub fn serialize<S, T>(value: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
28where
29 S: Serializer,
30 T: Serialize,
31{
32 match value {
33 Some(t) => t.serialize(serializer),
34 None => serializer.serialize_str(""),
35 }
36}
37
38pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
39where
40 D: Deserializer<'de>,
41 T: Deserialize<'de>,
42{
43 use serde_content::{Deserializer, Value};
44
45 let v = Value::deserialize(deserializer)?;
47
48 if let Value::String(s) = &v
49 && s.is_empty()
50 {
51 return Ok(None);
52 }
53
54 let t = Deserializer::new(v)
56 .human_readable()
57 .coerce_numbers()
58 .deserialize()
59 .map_err(D::Error::custom)?;
60
61 Ok(Some(t))
62}
63
64#[cfg(test)]
65mod tests {
66 use expect_test::expect;
67 use serde_default::DefaultFromSerde;
68
69 use super::*;
70
71 fn default_b() -> Option<usize> {
72 Some(42)
73 }
74
75 #[derive(Serialize, Deserialize, PartialEq, Debug, DefaultFromSerde)]
76 struct Config {
77 #[serde(with = "super")]
78 #[serde(default)]
79 a: Option<usize>,
80
81 #[serde(with = "super")]
82 #[serde(default = "default_b")]
83 b: Option<usize>,
84 }
85
86 #[test]
87 fn test_basic() {
88 let config = Config::default();
89 let toml = toml::to_string(&config).unwrap();
90 expect![[r#"
91 a = ""
92 b = 42
93 "#]]
94 .assert_eq(&toml);
95
96 let config2: Config = toml::from_str(&toml).unwrap();
97 assert_eq!(config2, config);
98 }
99}