use crate::task_manager::TaskPayload; use chrono::{DateTime, Local}; use serde::{de, Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::fmt::Display; #[derive(Deserialize, Serialize, Debug)] pub struct DocumentPayload { title: String, summary: Option, url: String, #[serde(deserialize_with = "single_or_vec")] tags: Vec, published_date: DateTime, location: String, } impl Display for DocumentPayload { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "{}", serde_json::to_string_pretty(self).map_err(|_| std::fmt::Error)? ) } } impl TaskPayload for DocumentPayload { fn get_key(&self) -> String { self.url.clone() } } 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")), }) }