1use chrono::{DateTime, Utc};
4use macros::make_path_parts;
5use serde::{Deserialize, Serialize};
6
7use crate::api::endpoints::PathPart;
8
9wrap_uuid! {
10 pub struct ImageStyleId
12}
13
14wrap_uuid! {
15 pub struct AnimationStyleId
17}
18
19wrap_uuid! {
20 pub struct AudioStyleId
22}
23
24wrap_uuid! {
25 pub struct AgeRangeId
27}
28
29wrap_uuid! {
30 pub struct AffiliationId
32}
33
34wrap_uuid! {
35 pub struct ResourceTypeId
37}
38
39wrap_uuid! {
40 pub struct SubjectId
42}
43
44wrap_uuid! {
45 pub struct ReportId
47}
48
49#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Debug, Hash)]
54#[cfg_attr(feature = "backend", derive(sqlx::Type))]
55#[cfg_attr(feature = "backend", sqlx(transparent))]
56pub struct ImageTagIndex(pub i16);
57
58into_i16_index!(ImageTagIndex);
59
60make_path_parts!(GetMetadataPath => "/v1/metadata");
61
62#[derive(Serialize, Deserialize, Debug, Clone)]
64pub struct ImageStyle {
65 pub id: ImageStyleId,
67
68 pub display_name: String,
70
71 pub created_at: DateTime<Utc>,
73
74 pub updated_at: Option<DateTime<Utc>>,
76}
77
78#[derive(Serialize, Deserialize, Debug, Clone)]
80pub struct AnimationStyle {
81 pub id: AnimationStyleId,
83
84 pub display_name: String,
86
87 pub created_at: DateTime<Utc>,
89
90 pub updated_at: Option<DateTime<Utc>>,
92}
93
94#[derive(Serialize, Deserialize, Debug)]
96pub struct PdfStyle {
97 pub id: ImageStyleId,
99
100 pub display_name: String,
102
103 pub created_at: DateTime<Utc>,
105
106 pub updated_at: Option<DateTime<Utc>>,
108}
109
110#[derive(Clone, Serialize, Deserialize, Debug)]
112pub struct AgeRange {
113 pub id: AgeRangeId,
115
116 pub display_name: String,
118
119 pub short_display_name: Option<String>,
121
122 pub created_at: DateTime<Utc>,
124
125 pub updated_at: Option<DateTime<Utc>>,
127}
128
129#[derive(Serialize, Deserialize, Debug, Clone)]
131pub struct Affiliation {
132 pub id: AffiliationId,
134
135 pub display_name: String,
137
138 pub created_at: DateTime<Utc>,
140
141 pub updated_at: Option<DateTime<Utc>>,
143}
144
145#[derive(Clone, Serialize, Deserialize, Debug)]
147pub struct ResourceType {
148 pub id: ResourceTypeId,
150
151 pub display_name: String,
153
154 pub created_at: DateTime<Utc>,
156
157 pub updated_at: Option<DateTime<Utc>>,
159}
160
161#[derive(Serialize, Deserialize, Debug, Clone)]
163pub struct Subject {
164 pub id: SubjectId,
166
167 pub display_name: String,
169
170 pub created_at: DateTime<Utc>,
172
173 pub updated_at: Option<DateTime<Utc>>,
175}
176
177#[derive(Serialize, Deserialize, Debug, Clone)]
179pub struct ImageTag {
180 pub index: ImageTagIndex,
182
183 pub display_name: String,
185
186 pub created_at: DateTime<Utc>,
188
189 pub updated_at: Option<DateTime<Utc>>,
191}
192
193#[derive(Serialize, Deserialize, Debug, Clone)]
195pub struct MetadataResponse {
196 pub image_styles: Vec<ImageStyle>,
198
199 pub animation_styles: Vec<AnimationStyle>,
201
202 pub age_ranges: Vec<AgeRange>,
207
208 pub affiliations: Vec<Affiliation>,
210
211 pub resource_types: Vec<ResourceType>,
213
214 pub subjects: Vec<Subject>,
216
217 pub image_tags: Vec<ImageTag>,
219}
220
221#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
223pub enum MetaKind {
224 Affiliation,
226
227 ResourceType,
229
230 ImageStyle,
232
233 AnimationStyle,
235
236 AgeRange,
238
239 Category,
241
242 Subject,
244
245 Tag,
247}
248
249#[derive(Clone, Serialize, Deserialize, Debug)]
251pub struct GoogleLocation {
252 pub input: String,
254 pub place: GooglePlace,
256}
257
258#[derive(Clone, Serialize, Deserialize, Debug)]
260pub struct GooglePlace {
261 pub address_components: Vec<GoogleAddressComponent>,
263}
264
265impl GooglePlace {
266 pub fn address_component_by_type(
268 &self,
269 address_type: GoogleAddressType,
270 ) -> Option<&GoogleAddressComponent> {
271 self.address_components.iter().find(|component| {
272 component
273 .types
274 .iter()
275 .find(|t| **t == address_type)
276 .is_some()
277 })
278 }
279}
280
281#[derive(Clone, Serialize, Deserialize, Debug)]
283pub struct GoogleAddressComponent {
284 pub long_name: String,
286 pub short_name: String,
288 pub types: Vec<GoogleAddressType>,
290}
291
292impl std::fmt::Display for GoogleAddressComponent {
293 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
294 write!(f, "{}", self.long_name)
295 }
296}
297
298impl From<&GoogleAddressComponent> for String {
299 fn from(component: &GoogleAddressComponent) -> String {
300 format!("{}", component)
301 }
302}
303
304#[derive(Clone, Serialize, Eq, PartialEq, Deserialize, Debug)]
306#[serde(rename_all = "snake_case")]
307pub enum GoogleAddressType {
308 Locality,
310 Sublocality,
312 PostalCode,
314 Country,
316 #[serde(rename = "administrative_area_level_1")]
318 AdministrativeAreaLevel1,
319 #[serde(rename = "administrative_area_level_2")]
321 AdministrativeAreaLevel2,
322 Political,
324 #[serde(untagged)]
326 Other(String),
327}