yggdrasil/models/
comment.rs1use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
11#[serde(rename_all = "lowercase")]
12pub enum CommentStatus {
13 Pending,
15 Approved,
17 Spam,
19 Trash,
21}
22
23impl CommentStatus {
24 #[cfg(feature = "server")]
26 pub fn from_str(s: &str) -> Self {
27 match s {
28 "approved" => Self::Approved,
29 "spam" => Self::Spam,
30 "trash" => Self::Trash,
31 _ => Self::Pending,
32 }
33 }
34
35 #[cfg(test)]
37 pub fn as_str(&self) -> &'static str {
38 match self {
39 Self::Pending => "pending",
40 Self::Approved => "approved",
41 Self::Spam => "spam",
42 Self::Trash => "trash",
43 }
44 }
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
49pub struct PublicComment {
50 pub id: i64,
52 pub parent_id: Option<i64>,
54 pub depth: i32,
56 pub author_name: String,
58 pub author_url: Option<String>,
60 pub avatar_url: String,
62 pub is_author: bool,
64 pub content_html: Option<String>,
66 pub created_at: String,
68 pub created_at_iso: String,
70}
71
72#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
74pub struct AdminComment {
75 pub id: i64,
77 pub post_id: i32,
79 pub post_title: String,
81 pub post_slug: String,
83 pub parent_id: Option<i64>,
85 pub depth: i32,
87 pub author_name: String,
89 pub author_email: String,
91 pub author_url: Option<String>,
93 pub avatar_url: String,
95 pub content_md: String,
97 pub status: CommentStatus,
99 pub created_at: DateTime<Utc>,
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
108 #[cfg(feature = "server")]
109 fn comment_status_from_str() {
110 assert_eq!(CommentStatus::from_str("pending"), CommentStatus::Pending);
111 assert_eq!(CommentStatus::from_str("approved"), CommentStatus::Approved);
112 assert_eq!(CommentStatus::from_str("spam"), CommentStatus::Spam);
113 assert_eq!(CommentStatus::from_str("trash"), CommentStatus::Trash);
114 }
115
116 #[test]
117 #[cfg(feature = "server")]
118 fn comment_status_from_str_unknown_defaults_to_pending() {
119 assert_eq!(CommentStatus::from_str("unknown"), CommentStatus::Pending);
120 assert_eq!(CommentStatus::from_str(""), CommentStatus::Pending);
121 }
122
123 #[test]
124 fn comment_status_as_str() {
125 assert_eq!(CommentStatus::Pending.as_str(), "pending");
126 assert_eq!(CommentStatus::Approved.as_str(), "approved");
127 assert_eq!(CommentStatus::Spam.as_str(), "spam");
128 assert_eq!(CommentStatus::Trash.as_str(), "trash");
129 }
130
131 #[test]
132 fn comment_status_serde_roundtrip() {
133 let statuses = vec![
134 CommentStatus::Pending,
135 CommentStatus::Approved,
136 CommentStatus::Spam,
137 CommentStatus::Trash,
138 ];
139 for status in statuses {
140 let json = serde_json::to_string(&status).unwrap();
141 let expected = format!("\"{}\"", status.as_str());
142 assert_eq!(json, expected);
143 let deserialized: CommentStatus = serde_json::from_str(&json).unwrap();
144 assert_eq!(deserialized, status);
145 }
146 }
147
148 #[test]
149 fn comment_status_deserialize_from_lowercase() {
150 let pending: CommentStatus = serde_json::from_str("\"pending\"").unwrap();
151 assert_eq!(pending, CommentStatus::Pending);
152 let approved: CommentStatus = serde_json::from_str("\"approved\"").unwrap();
153 assert_eq!(approved, CommentStatus::Approved);
154 }
155}