shared/domain/meta.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
//! Types for metadata.
use chrono::{DateTime, Utc};
use macros::make_path_parts;
use serde::{Deserialize, Serialize};
use crate::api::endpoints::PathPart;
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`ImageStyle::id`].
pub struct ImageStyleId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`AnimationStyle::id`].
pub struct AnimationStyleId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`AudioStyle::id`]. Note: not yet implemented
pub struct AudioStyleId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`AgeRange::id`].
pub struct AgeRangeId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`Affiliation::id`].
pub struct AffiliationId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`AdditionalResource::id`].
pub struct ResourceTypeId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`Subject::id`].
pub struct SubjectId
}
wrap_uuid! {
/// Wrapper type around [`Uuid`], represents [`Report::id`].
pub struct ReportId
}
/// Wrapper type around [`i16`](std::i16), represents the index of an image tag.
///
/// This is used instead of UUIDs for image tags as they aren't created dynamically and
/// a simple and consistent way to identify them is desired.
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Debug, Hash)]
#[cfg_attr(feature = "backend", derive(sqlx::Type))]
#[cfg_attr(feature = "backend", sqlx(transparent))]
pub struct ImageTagIndex(pub i16);
into_i16_index!(ImageTagIndex);
make_path_parts!(GetMetadataPath => "/v1/metadata");
/// Represents an image style.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ImageStyle {
/// The id of the image style.
pub id: ImageStyleId,
/// The image style's name.
pub display_name: String,
/// When the image style was created.
pub created_at: DateTime<Utc>,
/// When the image style was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents an animation style.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AnimationStyle {
/// The id of the animation style.
pub id: AnimationStyleId,
/// The animation style's name.
pub display_name: String,
/// When the animation style was created.
pub created_at: DateTime<Utc>,
/// When the animation style was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents an image style.
#[derive(Serialize, Deserialize, Debug)]
pub struct PdfStyle {
/// The id of the image style.
pub id: ImageStyleId,
/// The image style's name.
pub display_name: String,
/// When the image style was created.
pub created_at: DateTime<Utc>,
/// When the image style was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents a age range.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct AgeRange {
/// The id of the age range.
pub id: AgeRangeId,
/// The age range's name.
pub display_name: String,
/// The age range's abbreviated name.
pub short_display_name: Option<String>,
/// When the age range was created.
pub created_at: DateTime<Utc>,
/// When the age range was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents an affiliation.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Affiliation {
/// The id of the affiliation.
pub id: AffiliationId,
/// The affiliation's name.
pub display_name: String,
/// When the affiliation was created.
pub created_at: DateTime<Utc>,
/// When the affiliation was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents an additional resource.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct ResourceType {
/// The id of the additional resource.
pub id: ResourceTypeId,
/// The additional resource name.
pub display_name: String,
/// When the age range was created.
pub created_at: DateTime<Utc>,
/// When the age range was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents a subject.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Subject {
/// The id of the subject.
pub id: SubjectId,
/// The subject's name.
pub display_name: String,
/// When the subject was created.
pub created_at: DateTime<Utc>,
/// When the subject was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Represents a tag.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ImageTag {
/// Index of the tag.
pub index: ImageTagIndex,
/// The tag's name.
pub display_name: String,
/// When the tag was created.
pub created_at: DateTime<Utc>,
/// When the tag was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
/// Response for fetching all metadata.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MetadataResponse {
/// All image styles the server has.
pub image_styles: Vec<ImageStyle>,
/// All animation styles the server has.
pub animation_styles: Vec<AnimationStyle>,
/// All audio...
// TODO
/// All age ranges the server has.
pub age_ranges: Vec<AgeRange>,
/// All affiliations the server has.
pub affiliations: Vec<Affiliation>,
/// All additional resources the server has.
pub resource_types: Vec<ResourceType>,
/// All subjects the server has.
pub subjects: Vec<Subject>,
/// All tags for images.
pub image_tags: Vec<ImageTag>,
}
/// Metadata kinds.
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
pub enum MetaKind {
/// [`Affiliation`]
Affiliation,
/// [`ResourceType`]
ResourceType,
/// [`ImageStyle`]
ImageStyle,
/// [`AnimationStyle`]
AnimationStyle,
/// [`AgeRange`]
AgeRange,
/// [`Category`](super::category::Category)
Category,
/// [`Subject`]
Subject,
/// [`ImageTag`]
Tag,
}
/// Representation of a Google autocomplete result
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct GoogleLocation {
/// Input text
pub input: String,
/// Place returned by Google
pub place: GooglePlace,
}
/// Representation of a Google Place
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct GooglePlace {
/// List of address components
pub address_components: Vec<GoogleAddressComponent>,
}
impl GooglePlace {
/// Finds the first address component of this Google Place which matches the Address Type
pub fn address_component_by_type(
&self,
address_type: GoogleAddressType,
) -> Option<&GoogleAddressComponent> {
self.address_components.iter().find(|component| {
component
.types
.iter()
.find(|t| **t == address_type)
.is_some()
})
}
}
/// Representation of a Google Address Component
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct GoogleAddressComponent {
/// Components long name
pub long_name: String,
/// Components short name
pub short_name: String,
/// List of address types associated with the component
pub types: Vec<GoogleAddressType>,
}
impl std::fmt::Display for GoogleAddressComponent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.long_name)
}
}
impl From<&GoogleAddressComponent> for String {
fn from(component: &GoogleAddressComponent) -> String {
format!("{}", component)
}
}
/// Representation of common Google Address Types
#[derive(Clone, Serialize, Eq, PartialEq, Deserialize, Debug)]
#[serde(rename_all = "snake_case")]
pub enum GoogleAddressType {
/// Indicates an incorporated city or town political entity
Locality,
/// Indicates a first-order civil entity below a locality
Sublocality,
/// Indicates a postal code as used to address postal mail within the country
PostalCode,
/// Indicates the national political entity
Country,
/// Indicates a first-order civil entity below the country level
#[serde(rename = "administrative_area_level_1")]
AdministrativeAreaLevel1,
/// Indicates a second-order civil entity below the country level
#[serde(rename = "administrative_area_level_2")]
AdministrativeAreaLevel2,
/// Indicates a political entity
Political,
/// Any other address type found [here](https://developers.google.com/maps/documentation/geocoding/requests-geocoding#Types)
#[serde(untagged)]
Other(String),
}