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 content_html: Option<String>,
64 pub created_at: String,
66 pub created_at_iso: String,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
72pub struct AdminComment {
73 pub id: i64,
75 pub post_id: i32,
77 pub post_title: String,
79 pub post_slug: String,
81 pub parent_id: Option<i64>,
83 pub depth: i32,
85 pub author_name: String,
87 pub author_email: String,
89 pub author_url: Option<String>,
91 pub avatar_url: String,
93 pub content_md: String,
95 pub status: CommentStatus,
97 pub created_at: DateTime<Utc>,
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 #[cfg(feature = "server")]
107 fn comment_status_from_str() {
108 assert_eq!(CommentStatus::from_str("pending"), CommentStatus::Pending);
109 assert_eq!(CommentStatus::from_str("approved"), CommentStatus::Approved);
110 assert_eq!(CommentStatus::from_str("spam"), CommentStatus::Spam);
111 assert_eq!(CommentStatus::from_str("trash"), CommentStatus::Trash);
112 }
113
114 #[test]
115 #[cfg(feature = "server")]
116 fn comment_status_from_str_unknown_defaults_to_pending() {
117 assert_eq!(CommentStatus::from_str("unknown"), CommentStatus::Pending);
118 assert_eq!(CommentStatus::from_str(""), CommentStatus::Pending);
119 }
120
121 #[test]
122 fn comment_status_as_str() {
123 assert_eq!(CommentStatus::Pending.as_str(), "pending");
124 assert_eq!(CommentStatus::Approved.as_str(), "approved");
125 assert_eq!(CommentStatus::Spam.as_str(), "spam");
126 assert_eq!(CommentStatus::Trash.as_str(), "trash");
127 }
128
129 #[test]
130 fn comment_status_serde_roundtrip() {
131 let statuses = vec![
132 CommentStatus::Pending,
133 CommentStatus::Approved,
134 CommentStatus::Spam,
135 CommentStatus::Trash,
136 ];
137 for status in statuses {
138 let json = serde_json::to_string(&status).unwrap();
139 let expected = format!("\"{}\"", status.as_str());
140 assert_eq!(json, expected);
141 let deserialized: CommentStatus = serde_json::from_str(&json).unwrap();
142 assert_eq!(deserialized, status);
143 }
144 }
145
146 #[test]
147 fn comment_status_deserialize_from_lowercase() {
148 let pending: CommentStatus = serde_json::from_str("\"pending\"").unwrap();
149 assert_eq!(pending, CommentStatus::Pending);
150 let approved: CommentStatus = serde_json::from_str("\"approved\"").unwrap();
151 assert_eq!(approved, CommentStatus::Approved);
152 }
153}