pub use album::*;
pub use analysis::*;
pub use artist::*;
pub use device::*;
pub use errors::*;
pub use playlist::*;
pub use track::*;
pub use user::*;
use crate::util::*;
use chrono::{DateTime, NaiveDate, Utc};
use isocountry::CountryCode;
use serde::{
de::{self, Visitor},
Serialize, Deserialize, Deserializer,
};
use std::collections::HashMap;
use std::fmt::{self, Formatter};
use std::time::Duration;
macro_rules! to_struct {
($(#[$attr:meta])* $name:ident { $($(#[$f_attr:meta])* $f_name:ident : $f_ty:ty,)* }) => {
$(#[$attr])*
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, Deserialize)]
pub struct $name {
$(
$(#[$f_attr])*
pub $f_name: $f_ty,
)*
}
}
}
mod album;
mod analysis;
mod artist;
mod device;
mod errors;
mod playlist;
mod track;
mod user;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Category {
pub icons: Vec<Image>,
pub id: String,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Copyright {
pub text: String,
#[serde(rename = "type", with = "serde_is_p")]
pub performance_copyright: bool,
}
mod serde_is_p {
use serde::{Serializer, Deserializer, de::{self, Visitor}};
use std::fmt::{self, Formatter};
pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
struct CopyrightType;
impl<'de> Visitor<'de> for CopyrightType {
type Value = bool;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
f.write_str("P or C")
}
fn visit_str<E: de::Error>(self, s: &str) -> Result<Self::Value, E> {
match s {
"P" => Ok(true),
"C" => Ok(false),
_ => Err(de::Error::invalid_value(de::Unexpected::Str(s), &self)),
}
}
}
deserializer.deserialize_str(CopyrightType)
}
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn serialize<S: Serializer>(v: &bool, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(if *v {
"P"
} else {
"C"
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Followers {
pub total: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Image {
pub url: String,
pub height: Option<usize>,
pub width: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Page<T> {
pub items: Vec<T>,
pub limit: usize,
pub offset: usize,
pub total: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CursorPage<T> {
pub items: Vec<T>,
pub limit: usize,
pub cursors: Cursor,
pub total: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Cursor {
pub after: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TwoWayCursorPage<T> {
pub items: Vec<T>,
pub limit: usize,
pub cursors: TwoWayCursor,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TwoWayCursor {
pub after: Option<String>,
pub before: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Recommendations {
pub seeds: Vec<RecommendationSeed>,
pub tracks: Vec<TrackSimplified>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RecommendationSeed {
pub after_filtering_size: usize,
pub after_relinking_size: usize,
pub id: String,
pub initial_pool_size: usize,
#[serde(rename = "type")]
pub entity_type: SeedType,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum SeedType {
Artist,
Track,
Genre,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DatePrecision {
Year,
Month,
Day,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Restrictions {
pub reason: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ItemType {
Album,
Artist,
Playlist,
Track,
}
impl ItemType {
pub fn as_str(self) -> &'static str {
match self {
Self::Album => "album",
Self::Artist => "artist",
Self::Playlist => "playlist",
Self::Track => "track",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SearchResults {
pub artists: Option<Page<Artist>>,
pub albums: Option<Page<AlbumSimplified>>,
pub tracks: Option<Page<Track>>,
pub playlists: Option<Page<PlaylistSimplified>>,
}