use chrono::{DateTime, Local}; use serde::{Deserialize, Deserializer, de}; use serde_json::Value; #[derive(Deserialize)] pub struct DocumentPayload { title: String, summary: Option, url: String, #[serde(deserialize_with = "single_or_vec")] tags: Vec, published_date: DateTime, location: String, } fn str_to_int<'de, D: Deserializer<'de>>(deserializer: D) -> Result { Ok(match Value::deserialize(deserializer)? { Value::String(s) => s.parse().map_err(de::Error::custom)?, Value::Number(num) => num.as_u64().ok_or(de::Error::custom("Invalid number"))?, _ => return Err(de::Error::custom("wrong type")), }) } fn str_to_bool<'de, D: Deserializer<'de>>(deserializer: D) -> Result { Ok(match Value::deserialize(deserializer)? { Value::String(s) => s.parse().map_err(de::Error::custom)?, Value::Bool(b) => b, _ => return Err(de::Error::custom("wrong type")), }) } fn single_or_vec<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { Ok(match Value::deserialize(deserializer)? { Value::String(s) => vec![s.parse().map_err(de::Error::custom)?], Value::Array(arr) => arr.into_iter().map(|a| a.to_string()).collect(), Value::Null => Vec::new(), _ => return Err(de::Error::custom("wrong type")), }) }