Skip to main content

systemprompt_files/models/
content_file.rs

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