Skip to main content

systemprompt_files/models/
metadata.rs

1use serde::{Deserialize, Serialize};
2
3pub use super::image_metadata::ImageMetadata;
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize)]
6pub struct FileMetadata {
7    #[serde(default, skip_serializing_if = "Option::is_none")]
8    pub checksums: Option<FileChecksums>,
9
10    #[serde(default, skip_serializing_if = "Option::is_none")]
11    pub type_specific: Option<TypeSpecificMetadata>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(tag = "type", rename_all = "snake_case")]
16pub enum TypeSpecificMetadata {
17    Image(ImageMetadata),
18    Document(DocumentMetadata),
19    Audio(AudioMetadata),
20    Video(VideoMetadata),
21}
22
23#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct DocumentMetadata {
25    #[serde(default, skip_serializing_if = "Option::is_none")]
26    pub title: Option<String>,
27
28    #[serde(default, skip_serializing_if = "Option::is_none")]
29    pub author: Option<String>,
30
31    #[serde(default, skip_serializing_if = "Option::is_none")]
32    pub page_count: Option<u32>,
33}
34
35#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
36pub struct AudioMetadata {
37    #[serde(default, skip_serializing_if = "Option::is_none")]
38    pub duration_seconds: Option<f32>,
39
40    #[serde(default, skip_serializing_if = "Option::is_none")]
41    pub sample_rate: Option<u32>,
42
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub channels: Option<u8>,
45}
46
47#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
48pub struct VideoMetadata {
49    #[serde(default, skip_serializing_if = "Option::is_none")]
50    pub width: Option<u32>,
51
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub height: Option<u32>,
54
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub duration_seconds: Option<f32>,
57
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub frame_rate: Option<f32>,
60}
61
62#[derive(Debug, Clone, Default, Serialize, Deserialize)]
63pub struct FileChecksums {
64    #[serde(default, skip_serializing_if = "Option::is_none")]
65    pub md5: Option<String>,
66
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub sha256: Option<String>,
69}
70
71impl FileMetadata {
72    pub const fn new() -> Self {
73        Self {
74            checksums: None,
75            type_specific: None,
76        }
77    }
78
79    pub fn with_image(mut self, image: ImageMetadata) -> Self {
80        self.type_specific = Some(TypeSpecificMetadata::Image(image));
81        self
82    }
83
84    pub fn with_document(mut self, doc: DocumentMetadata) -> Self {
85        self.type_specific = Some(TypeSpecificMetadata::Document(doc));
86        self
87    }
88
89    pub fn with_audio(mut self, audio: AudioMetadata) -> Self {
90        self.type_specific = Some(TypeSpecificMetadata::Audio(audio));
91        self
92    }
93
94    pub fn with_video(mut self, video: VideoMetadata) -> Self {
95        self.type_specific = Some(TypeSpecificMetadata::Video(video));
96        self
97    }
98
99    pub fn with_checksums(mut self, checksums: FileChecksums) -> Self {
100        self.checksums = Some(checksums);
101        self
102    }
103}
104
105impl DocumentMetadata {
106    pub const fn new() -> Self {
107        Self {
108            title: None,
109            author: None,
110            page_count: None,
111        }
112    }
113
114    pub fn with_title(mut self, title: impl Into<String>) -> Self {
115        self.title = Some(title.into());
116        self
117    }
118
119    pub fn with_author(mut self, author: impl Into<String>) -> Self {
120        self.author = Some(author.into());
121        self
122    }
123
124    pub const fn with_page_count(mut self, page_count: u32) -> Self {
125        self.page_count = Some(page_count);
126        self
127    }
128}
129
130impl AudioMetadata {
131    pub const fn new() -> Self {
132        Self {
133            duration_seconds: None,
134            sample_rate: None,
135            channels: None,
136        }
137    }
138
139    pub const fn with_duration_seconds(mut self, duration: f32) -> Self {
140        self.duration_seconds = Some(duration);
141        self
142    }
143
144    pub const fn with_sample_rate(mut self, sample_rate: u32) -> Self {
145        self.sample_rate = Some(sample_rate);
146        self
147    }
148
149    pub const fn with_channels(mut self, channels: u8) -> Self {
150        self.channels = Some(channels);
151        self
152    }
153}
154
155impl VideoMetadata {
156    pub const fn new() -> Self {
157        Self {
158            width: None,
159            height: None,
160            duration_seconds: None,
161            frame_rate: None,
162        }
163    }
164
165    pub const fn with_dimensions(mut self, width: u32, height: u32) -> Self {
166        self.width = Some(width);
167        self.height = Some(height);
168        self
169    }
170
171    pub const fn with_duration_seconds(mut self, duration: f32) -> Self {
172        self.duration_seconds = Some(duration);
173        self
174    }
175
176    pub const fn with_frame_rate(mut self, frame_rate: f32) -> Self {
177        self.frame_rate = Some(frame_rate);
178        self
179    }
180}
181
182impl FileChecksums {
183    pub const fn new() -> Self {
184        Self {
185            md5: None,
186            sha256: None,
187        }
188    }
189
190    pub fn with_md5(mut self, md5: impl Into<String>) -> Self {
191        self.md5 = Some(md5.into());
192        self
193    }
194
195    pub fn with_sha256(mut self, sha256: impl Into<String>) -> Self {
196        self.sha256 = Some(sha256.into());
197        self
198    }
199}