Want to contribute? Fork me on Codeberg.org!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
1.5 KiB

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 {
pub id: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<String>, // None is Anonymous
#[serde(rename(serialize = "gravatar"))]
#[serde(serialize_with = "serialize_gravatar")]
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[validate(length(min = 1))]
pub text: String,
#[serde(with = "ts_seconds_option")]
#[serde(skip_serializing_if = "Option::is_none")]
pub timestamp: Option<DateTime<Utc>>,
pub content_id: String,
pub parent: Option<i64>,
#[serde(skip_serializing_if = "<[_]>::is_empty")]
pub replies: Vec<Comment>,
pub fn get_gravatar(email: &Option<String>) -> String {
match email {
Some(email) => format!("{:x}", md5::compute(email.to_lowercase())),
None => String::from(""),
fn serialize_gravatar<S>(email: &Option<String>, s: S) -> Result<S::Ok, S::Error>
S: Serializer,
match email {
Some(_) => s.serialize_some(&get_gravatar(email)),
None => s.serialize_none(),