aboutsummaryrefslogblamecommitdiffstats
path: root/src/deserialize.rs
blob: d774b14f525d3268afc0f77dbb3e7a4a258fbc3b (plain) (tree)
1
2
3
4
5
6
7
8
                                         


                              


                                           
                                                                                             




                                                                          
     











                                                                                                                        

                                                                                              


















                                                                                                             
     

                                            




                             





                                        



                             



                           
                           

 
                                                                          
                                  
           
                    



            



                             
                      
                           
                    



                             


                             
                   
                           
                         

 
 

                             
                     

                           
                         
                             
                           
                     
                    





                                        

                   
                                

                                         






                                        

 









                                         
                           










                              





                           
 
 

                             
                           


                             
                                



                             












                                        
                           



                            



                             
                
 
// SPDX-License-Identifier: AGPL-3.0-only
use std::collections::HashMap;
use std::sync::Arc;

use serde::{Deserialize, Deserializer, de};
use serde_json::Value;

fn str_num<'de, D, T>(d: D) -> Result<T, D::Error> where D: Deserializer<'de>, T: From<u64> {
  struct Visitor;
  impl<'v> de::Visitor<'v> for Visitor {
    type Value = u64;
    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
      write!(f, "a value which can be interpreted as a uint")
    }
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
      where E: de::Error
    {
      v.parse().map_err(|_| de::Error::invalid_value(de::Unexpected::Str(v), &"a string which can be parsed as a uint"))
    }
    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
      where E: de::Error
    {
      Ok(v)
    }
  }
  d.deserialize_any(Visitor).map(Into::into)
}
fn str_bool<'de, D, T>(d: D) -> Result<T, D::Error> where D: Deserializer<'de>, T: From<bool>{
  struct Visitor;
  impl<'v> de::Visitor<'v> for Visitor {
    type Value = bool;
    fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
      write!(f, "a value which can be interpreted as a uint")
    }
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
      where E: de::Error
    {
      match v.to_ascii_lowercase().as_str() {
        "true" | "1" => Ok(true),
        "false" | "0" => Ok(false),
        _ => Err(de::Error::invalid_value(de::Unexpected::Str(v), &"a string which can be parsed as a bool"))
      }
    }
    fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
      where E: de::Error
    {
      Ok(v)
    }
  }
  d.deserialize_any(Visitor).map(Into::into)
}


#[derive(Deserialize, Debug)]
pub struct TimeStamp {
  #[serde(alias = "unixtime")]
  #[serde(alias = "uts")]
  #[serde(deserialize_with = "str_num")]
  pub unix_timestamp: u64,
  #[serde(rename = "#text")]
  pub text: Value
}

#[derive(Deserialize, Debug)]
pub struct Artist {
  #[serde(alias = "#text")]
  pub name: Arc<str>,

  #[serde(default)]
  pub url: Option<Arc<str>>
}

#[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
#[serde(rename_all = "lowercase")]
#[repr(u8)]
pub enum ImageSize {
  Small,
  Medium,
  Large,
  ExtraLarge
}

#[derive(Deserialize, Debug)]
pub struct Image {
  pub size: ImageSize,
  #[serde(alias = "#text")]
  pub url: Arc<str>,
}

#[derive(Deserialize, Debug)]
pub struct Album {
  pub mbid: Option<Arc<str>>,
  #[serde(alias = "#text")]
  pub title: Arc<str>,
  #[serde(default)]
  #[serde(alias = "image")]
  pub images: Vec<Image>,
}


#[derive(Deserialize, Debug)]
pub struct Track {
  pub artist: Artist,
  #[serde(alias = "image")]
  #[serde(default)]
  pub images: Vec<Image>,
  pub mbid: Option<Arc<str>>,
  pub album: Option<Album>,
  pub name: Arc<str>,
  pub url: Arc<str>,
  #[serde(deserialize_with = "str_num")]
  pub duration: u64,
  #[serde(deserialize_with = "str_num")]
  pub listeners: u64,
  #[serde(deserialize_with = "str_num")]
  pub playcount: u64,

  #[serde(default)]
  #[serde(rename = "userloved")]
  #[serde(deserialize_with = "str_bool")]
  pub loved: Option<bool>,
  #[serde(deserialize_with = "str_num")]
  pub userplaycount: u64,
}

#[derive(Deserialize, Debug)]
pub struct GetTrackInfo {
  pub track: Track
}

#[derive(Default, Deserialize, Debug)]
pub struct TrackAttr {
  #[serde(default)]
  #[serde(deserialize_with = "str_bool")]
  pub nowplaying: bool,
  #[serde(flatten)]
  pub rest: HashMap<Arc<str>, Value>,
}
#[derive(Deserialize, Debug)]
pub struct ArtistStub {
  #[serde(alias = "#text")]
  pub name: Arc<str>
}
#[derive(Deserialize, Debug)]
pub struct TrackStub {
  pub name: Arc<str>,
  pub artist: ArtistStub,
  #[serde(default)]
  pub date: Option<TimeStamp>,
  #[serde(rename = "@attr")]
  #[serde(default)]
  pub attr: TrackAttr,
  #[serde(default)]
  #[serde(alias = "image")]
  pub images: Vec<Image>,

  #[serde(default)]
  pub album: Option<Album>
}

#[derive(Deserialize, Debug)]
pub struct RecentTracks {
  pub track: Vec<TrackStub>
}
#[derive(Deserialize, Debug)]
pub struct GetRecentTracks {
  pub recenttracks: RecentTracks
}

#[derive(Deserialize, Debug)]
pub struct User {
  pub name: Arc<str>,
  pub realname: Arc<str>,
  #[serde(deserialize_with = "str_num")]
  pub playcount: u64,
  #[serde(deserialize_with = "str_num")]
  pub artist_count: u64,
  #[serde(deserialize_with = "str_num")]
  pub playlists: u64,
  #[serde(deserialize_with = "str_num")]
  pub track_count: u64,
  #[serde(deserialize_with = "str_num")]
  pub album_count: u64,

  #[serde(alias = "image")]
  pub images: Vec<Image>,

  pub registered: TimeStamp,
  pub url: Arc<str>
}

#[derive(Deserialize, Debug)]
pub struct GetUserInfo {
  pub user: User
}