Skip to main content

systemprompt_files/models/
content_file.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use sqlx::FromRow;
4use systemprompt_identifiers::ContentId;
5
6use crate::error::{FilesError, FilesResult};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
9#[serde(rename_all = "lowercase")]
10pub enum FileRole {
11    Featured,
12    #[default]
13    Attachment,
14    Inline,
15    OgImage,
16    Thumbnail,
17}
18
19impl FileRole {
20    pub const fn as_str(&self) -> &'static str {
21        match self {
22            Self::Featured => "featured",
23            Self::Attachment => "attachment",
24            Self::Inline => "inline",
25            Self::OgImage => "og_image",
26            Self::Thumbnail => "thumbnail",
27        }
28    }
29
30    pub fn parse(s: &str) -> FilesResult<Self> {
31        match s.to_lowercase().as_str() {
32            "featured" => Ok(Self::Featured),
33            "attachment" => Ok(Self::Attachment),
34            "inline" => Ok(Self::Inline),
35            "og_image" => Ok(Self::OgImage),
36            "thumbnail" => Ok(Self::Thumbnail),
37            other => Err(FilesError::Validation(format!(
38                "invalid file role: {other}"
39            ))),
40        }
41    }
42}
43
44impl std::fmt::Display for FileRole {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        write!(f, "{}", self.as_str())
47    }
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
51pub struct ContentFile {
52    pub id: i32,
53    pub content_id: ContentId,
54    pub file_id: uuid::Uuid,
55    pub role: String,
56    pub display_order: i32,
57    pub created_at: DateTime<Utc>,
58}
59
60impl ContentFile {
61    pub fn parsed_role(&self) -> FilesResult<FileRole> {
62        FileRole::parse(&self.role)
63    }
64}