Skip to main content

pebble_cms/models/
content.rs

1use super::{Tag, UserSummary};
2use serde::{Deserialize, Serialize};
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
6#[serde(rename_all = "lowercase")]
7pub enum ContentType {
8    #[default]
9    Post,
10    Page,
11    Snippet,
12}
13
14impl FromStr for ContentType {
15    type Err = ();
16
17    fn from_str(s: &str) -> Result<Self, Self::Err> {
18        match s.to_lowercase().as_str() {
19            "post" => Ok(Self::Post),
20            "page" => Ok(Self::Page),
21            "snippet" => Ok(Self::Snippet),
22            _ => Err(()),
23        }
24    }
25}
26
27impl std::fmt::Display for ContentType {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Self::Post => write!(f, "post"),
31            Self::Page => write!(f, "page"),
32            Self::Snippet => write!(f, "snippet"),
33        }
34    }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
38#[serde(rename_all = "lowercase")]
39pub enum ContentStatus {
40    #[default]
41    Draft,
42    Scheduled,
43    Published,
44    Archived,
45}
46
47impl FromStr for ContentStatus {
48    type Err = ();
49
50    fn from_str(s: &str) -> Result<Self, Self::Err> {
51        match s.to_lowercase().as_str() {
52            "draft" => Ok(Self::Draft),
53            "scheduled" => Ok(Self::Scheduled),
54            "published" => Ok(Self::Published),
55            "archived" => Ok(Self::Archived),
56            _ => Err(()),
57        }
58    }
59}
60
61impl std::fmt::Display for ContentStatus {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        match self {
64            Self::Draft => write!(f, "draft"),
65            Self::Scheduled => write!(f, "scheduled"),
66            Self::Published => write!(f, "published"),
67            Self::Archived => write!(f, "archived"),
68        }
69    }
70}
71
72#[derive(Debug, Clone, Serialize)]
73pub struct Content {
74    pub id: i64,
75    pub slug: String,
76    pub title: String,
77    pub content_type: ContentType,
78    pub body_markdown: String,
79    pub body_html: String,
80    pub excerpt: Option<String>,
81    pub featured_image: Option<String>,
82    pub status: ContentStatus,
83    pub scheduled_at: Option<String>,
84    pub published_at: Option<String>,
85    pub author_id: Option<i64>,
86    pub metadata: serde_json::Value,
87    pub created_at: String,
88    pub updated_at: String,
89}
90
91#[derive(Debug, Clone, Serialize)]
92pub struct ContentWithTags {
93    #[serde(flatten)]
94    pub content: Content,
95    pub tags: Vec<Tag>,
96    pub author: Option<UserSummary>,
97}
98
99#[derive(Debug, Deserialize)]
100pub struct CreateContent {
101    pub title: String,
102    pub slug: Option<String>,
103    #[serde(default)]
104    pub content_type: ContentType,
105    #[serde(default)]
106    pub body_markdown: String,
107    pub excerpt: Option<String>,
108    pub featured_image: Option<String>,
109    #[serde(default)]
110    pub status: ContentStatus,
111    pub scheduled_at: Option<String>,
112    #[serde(default)]
113    pub tags: Vec<String>,
114    pub metadata: Option<serde_json::Value>,
115}
116
117#[derive(Debug, Deserialize, Default)]
118pub struct UpdateContent {
119    pub title: Option<String>,
120    pub slug: Option<String>,
121    pub body_markdown: Option<String>,
122    pub excerpt: Option<String>,
123    pub featured_image: Option<String>,
124    pub status: Option<ContentStatus>,
125    pub scheduled_at: Option<String>,
126    pub tags: Option<Vec<String>>,
127    pub metadata: Option<serde_json::Value>,
128}
129
130#[derive(Debug, Clone, Serialize)]
131pub struct ContentSummary {
132    pub id: i64,
133    pub slug: String,
134    pub title: String,
135    pub content_type: ContentType,
136    pub excerpt: Option<String>,
137    pub status: ContentStatus,
138    pub scheduled_at: Option<String>,
139    pub published_at: Option<String>,
140    pub created_at: String,
141}