azure_core/
util.rs
1use serde::{
4 de::{self, DeserializeOwned, Deserializer},
5 Deserialize,
6};
7
8pub fn case_insensitive_deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
9where
10 T: DeserializeOwned + std::fmt::Debug,
11 D: Deserializer<'de>,
12{
13 let v = String::deserialize(deserializer)?;
14 T::deserialize(serde_json::Value::String(v.clone()))
15 .or_else(|_| T::deserialize(serde_json::Value::String(v.to_lowercase())))
16 .map_err(de::Error::custom)
17}
18
19pub fn deserialize_null_as_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
22where
23 T: Default + Deserialize<'de>,
24 D: Deserializer<'de>,
25{
26 let opt = Option::deserialize(deserializer)?;
27 Ok(opt.unwrap_or_default())
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33 use crate::from_json;
34 use serde::Serialize;
35
36 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
37 pub struct SiteConfig {
38 #[serde(
39 rename = "appSettings",
40 default,
41 deserialize_with = "deserialize_null_as_default",
42 skip_serializing_if = "Vec::is_empty"
43 )]
44 pub app_settings: Vec<NameValuePair>,
45 }
46
47 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
48 pub struct NameValuePair {
49 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub name: Option<String>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub value: Option<String>,
53 }
54
55 #[test]
56 fn deserialize_empty() -> crate::Result<()> {
57 let bytes = br#"{}"#;
58 let site_config: SiteConfig = from_json(bytes)?;
59 assert_eq!(Vec::<NameValuePair>::default(), site_config.app_settings);
60 Ok(())
61 }
62
63 #[test]
64 fn deserialize_null() -> crate::Result<()> {
65 let bytes = br#"{ "appSettings": null }"#;
66 let site_config: SiteConfig = from_json(bytes)?;
67 assert_eq!(Vec::<NameValuePair>::default(), site_config.app_settings);
68 Ok(())
69 }
70}