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