use chrono::serde::ts_seconds_option; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize, Serializer}; use validator::Validate; #[derive(Serialize, Deserialize, Validate)] #[serde(rename_all = "camelCase")] pub struct Comment { #[serde(skip_deserializing)] pub id: Option, #[serde(skip_serializing_if = "Option::is_none")] pub author: Option, // None is Anonymous #[serde(rename(serialize = "gravatar"))] #[serde(serialize_with = "serialize_gravatar")] #[validate(email)] #[serde(skip_serializing_if = "Option::is_none")] pub email: Option, #[validate(length(min = 1))] pub text: String, #[serde(default)] #[serde(with = "ts_seconds_option")] #[serde(skip_serializing_if = "Option::is_none")] pub timestamp: Option>, #[serde(skip_serializing)] pub content_id: String, #[serde(skip_serializing)] pub parent: Option, #[serde(skip_serializing_if = "<[_]>::is_empty")] #[serde(skip_deserializing)] pub replies: Vec, } pub fn get_gravatar(email: &Option) -> String { match email { Some(email) => format!("{:x}", md5::compute(email.to_lowercase())), None => String::from(""), } } fn serialize_gravatar(email: &Option, s: S) -> Result where S: Serializer, { match email { Some(_) => s.serialize_some(&get_gravatar(email)), None => s.serialize_none(), } }