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