systemprompt_files/models/
metadata.rs1use 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}