use {
serde::{Deserialize, Deserializer, de::Error},
serde_json::{
Value::{self, Null, Object, String as SerdeString},
from_value,
},
};
use crate::models::album::Image;
fn deserialize_optional_value<'de, D>(deserializer: D) -> Result<Option<Value>, D::Error>
where
D: Deserializer<'de>,
{
Option::<Value>::deserialize(deserializer)
}
fn map_value_to_string(value: Option<Value>) -> Option<String> {
match value {
None | Some(Null) => None,
Some(SerdeString(s)) => Some(s),
Some(v) => Some(v.to_string()),
}
}
pub fn deserialize_flexible_name<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
let value = deserialize_optional_value(deserializer)?;
match value {
None | Some(Null) => Ok(None),
Some(SerdeString(s)) => Ok(Some(s)),
Some(Object(map)) => map
.get("display")
.and_then(Value::as_str)
.map(|s| Some(s.to_string()))
.ok_or_else(|| Error::custom("object missing 'display' field")),
Some(v) => Ok(map_value_to_string(Some(v))),
}
}
pub fn deserialize_flexible_string_id<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
let value = deserialize_optional_value(deserializer)?;
Ok(map_value_to_string(value))
}
pub fn deserialize_picture<'de, D>(deserializer: D) -> Result<Option<Image>, D::Error>
where
D: Deserializer<'de>,
{
let value = deserialize_optional_value(deserializer)?;
match value {
None | Some(Null | SerdeString(_)) => Ok(None),
Some(v) => from_value(v).map_err(Error::custom),
}
}