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