fjordgard

A desktop clock application
Log | Files | Refs | README | LICENSE

model.rs (5659B)


      1 use std::{collections::HashMap, fmt::Display};
      2 
      3 use serde::{Deserialize, Serialize, Serializer};
      4 use strum::Display;
      5 
      6 #[derive(Deserialize, Debug)]
      7 #[serde(untagged)]
      8 pub(crate) enum UnsplashResponse {
      9     Error { errors: Vec<String> },
     10     Success(serde_json::Value),
     11 }
     12 
     13 #[derive(Serialize)]
     14 #[serde(rename = "lowercase")]
     15 pub enum Orientation {
     16     Landscape,
     17     Portrait,
     18     Squarish,
     19 }
     20 
     21 #[serde_with::skip_serializing_none]
     22 #[derive(Serialize, Default)]
     23 pub struct CollectionPhotosOptions {
     24     pub page: Option<usize>,
     25     pub per_page: Option<usize>,
     26     pub orientation: Option<Orientation>,
     27 }
     28 
     29 #[derive(Deserialize, Debug, Clone)]
     30 pub struct CollectionPhotos {
     31     pub collection_total: usize,
     32     pub per_page: usize,
     33     pub photos: Vec<Photo>,
     34 }
     35 
     36 #[derive(Deserialize, Debug, Clone)]
     37 pub struct Photo {
     38     pub id: String,
     39     pub slug: String,
     40     pub alternative_slugs: HashMap<String, String>,
     41     pub created_at: String,
     42     pub updated_at: String,
     43     pub promoted_at: Option<String>,
     44     pub width: usize,
     45     pub height: usize,
     46     pub color: String,
     47     pub blur_hash: String,
     48     pub description: Option<String>,
     49     pub alt_description: Option<String>,
     50     pub urls: PhotoUrls,
     51     pub links: PhotoLinks,
     52     pub likes: usize,
     53     pub liked_by_user: bool,
     54     pub topic_submissions: HashMap<String, TopicSubmission>,
     55     pub asset_type: String,
     56     pub user: User,
     57 }
     58 
     59 #[derive(Deserialize, Debug, Clone)]
     60 pub struct PhotoUrls {
     61     pub raw: String,
     62     pub full: String,
     63     pub regular: String,
     64     pub small: String,
     65     pub thumb: String,
     66     pub small_s3: String,
     67 }
     68 
     69 #[derive(Deserialize, Debug, Clone)]
     70 pub struct PhotoLinks {
     71     #[serde(rename = "self")]
     72     pub this: String,
     73     pub html: String,
     74     pub download: String,
     75     pub download_location: String,
     76 }
     77 
     78 #[derive(Deserialize, Debug, Clone)]
     79 pub struct TopicSubmission {
     80     pub status: String,
     81     pub approved_on: String,
     82 }
     83 
     84 #[derive(Deserialize, Debug, Clone)]
     85 pub struct User {
     86     pub id: String,
     87     pub updated_at: String,
     88     pub username: String,
     89     pub first_name: String,
     90     pub last_name: Option<String>,
     91     pub twitter_username: Option<String>,
     92     pub portfolio_url: Option<String>,
     93     pub bio: Option<String>,
     94     pub location: Option<String>,
     95     pub links: UserLinks,
     96     pub profile_image: ProfileImageLinks,
     97     pub instagram_username: Option<String>,
     98     pub total_collections: usize,
     99     pub total_likes: usize,
    100     pub total_photos: usize,
    101     pub total_promoted_photos: usize,
    102     pub total_illustrations: usize,
    103     pub total_promoted_illustrations: usize,
    104     pub accepted_tos: bool,
    105     pub for_hire: bool,
    106     // a bit redundant aye unsplash
    107     pub social: UserSocials,
    108 }
    109 
    110 #[derive(Deserialize, Debug, Clone)]
    111 pub struct UserLinks {
    112     #[serde(rename = "self")]
    113     pub this: String,
    114     pub html: String,
    115     pub photos: String,
    116     pub likes: String,
    117     pub portfolio: String,
    118     pub following: Option<String>,
    119     pub followers: Option<String>,
    120 }
    121 
    122 #[derive(Deserialize, Debug, Clone)]
    123 pub struct ProfileImageLinks {
    124     pub small: String,
    125     pub medium: String,
    126     pub large: String,
    127 }
    128 
    129 #[derive(Deserialize, Debug, Clone)]
    130 pub struct UserSocials {
    131     pub instagram_username: Option<String>,
    132     pub portfolio_url: Option<String>,
    133     pub twitter_username: Option<String>,
    134     pub paypal_email: Option<String>,
    135 }
    136 
    137 #[derive(Display)]
    138 #[strum(serialize_all = "lowercase")]
    139 pub enum Crop {
    140     Top,
    141     Bottom,
    142     Left,
    143     Right,
    144     Faces,
    145     FocalPoint,
    146     Edges,
    147     Entropy,
    148 }
    149 
    150 #[derive(Serialize)]
    151 #[serde(rename = "lowercase")]
    152 pub enum Format {
    153     Avif,
    154     Gif,
    155     Jp2,
    156     Jpg,
    157     Json,
    158     Jxr,
    159     PJpg,
    160     Mp4,
    161     Png,
    162     Png8,
    163     Png32,
    164     Webm,
    165     Webp,
    166     BlurHash,
    167 }
    168 
    169 #[derive(Serialize)]
    170 #[serde(rename = "lowercase")]
    171 pub enum Auto {
    172     Compress,
    173     Enhance,
    174     True,
    175     Format,
    176     Redeye,
    177 }
    178 
    179 #[derive(Serialize)]
    180 #[serde(rename = "lowercase")]
    181 pub enum Fit {
    182     Clamp,
    183     Clip,
    184     Crop,
    185     FaceArea,
    186     Fill,
    187     FillMax,
    188     Max,
    189     Min,
    190     Scale,
    191 }
    192 
    193 #[serde_with::skip_serializing_none]
    194 #[derive(Serialize, Default)]
    195 pub struct PhotoFetchOptions {
    196     pub w: Option<f64>,
    197     pub h: Option<f64>,
    198     #[serde(serialize_with = "csv")]
    199     pub crop: Option<Vec<Crop>>,
    200     pub fm: Option<Format>,
    201     pub auto: Option<Auto>,
    202     pub q: Option<usize>,
    203     pub fit: Option<Fit>,
    204     pub dpr: Option<usize>,
    205 }
    206 
    207 fn csv<S: Serializer, T: Display>(list: &Option<Vec<T>>, serializer: S) -> Result<S::Ok, S::Error> {
    208     if let Some(list) = list {
    209         let s: String = list
    210             .iter()
    211             .map(|v| v.to_string())
    212             .collect::<Vec<String>>()
    213             .join(",");
    214 
    215         serializer.serialize_str(&s)
    216     } else {
    217         serializer.serialize_none()
    218     }
    219 }
    220 
    221 #[derive(Deserialize, Debug, Clone)]
    222 pub struct CollectionLinks {
    223     #[serde(rename = "self")]
    224     pub this: String,
    225     pub html: String,
    226     pub photos: String,
    227     pub related: String,
    228 }
    229 
    230 #[derive(Deserialize, Debug, Clone)]
    231 pub struct PreviewPhoto {
    232     pub id: String,
    233     pub slug: String,
    234     pub created_at: String,
    235     pub updated_at: String,
    236     pub blur_hash: String,
    237     pub asset_type: String,
    238     pub urls: PhotoUrls,
    239 }
    240 
    241 #[derive(Deserialize, Debug, Clone)]
    242 pub struct Collection {
    243     pub id: String,
    244     pub title: String,
    245     pub description: Option<String>,
    246     pub published_at: String,
    247     pub last_collected_at: String,
    248     pub updated_at: String,
    249     pub featured: bool,
    250     pub total_photos: usize,
    251     pub private: bool,
    252     pub share_key: String,
    253     pub links: CollectionLinks,
    254     pub user: User,
    255     pub cover_photo: Option<Photo>,
    256     pub preview_photos: Vec<PreviewPhoto>,
    257 }