azure_core/
util.rs

1//! An assortment of helper utilities.
2
3use 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
19/// Deserialize JSON null as default
20/// <https://github.com/serde-rs/serde/issues/1098>
21pub 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}