Skip to content

Commit

Permalink
Workaround for Spotify API bug
Browse files Browse the repository at this point in the history
Due to Spotify API returning floats instead of uints for some fields of
the Artist it cannot be parsed. This commit adds deserializing float
values into u32 as a workaround.

Related issue: [issue](#452)

Signed-off-by: Maciej Torhan <[email protected]>
  • Loading branch information
m-torhan committed Feb 2, 2024
1 parent 6b23c52 commit 5d2ae3a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 4 deletions.
6 changes: 5 additions & 1 deletion rspotify-model/src/artist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ use serde::{Deserialize, Serialize};

use std::collections::HashMap;

use crate::{ArtistId, CursorBasedPage, Followers, Image};
use crate::{
data_type_patcher::data_type_patcher::as_u32, ArtistId, CursorBasedPage, Followers, Image,
};

/// Simplified Artist Object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
Expand All @@ -25,6 +27,8 @@ pub struct FullArtist {
pub id: ArtistId<'static>,
pub images: Vec<Image>,
pub name: String,
// TODO: remove this statement after Spotify fix the [issue](https://github.com/ramsayleung/rspotify/issues/452)
#[serde(deserialize_with = "as_u32")]
pub popularity: u32,
}

Expand Down
30 changes: 30 additions & 0 deletions rspotify-model/src/data_type_patcher.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Workaround for Spotify API bug which causes dome uint fields
// being return as floats
// TODO: remove this workaround after Spotify fix the [issue](https://github.com/ramsayleung/rspotify/issues/452)

pub mod data_type_patcher {

Check failure on line 5 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-ureq,rspotify/ureq-...

module has the same name as its containing module

Check failure on line 5 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-reqwest,rspotify/re...

module has the same name as its containing module
use serde::{Deserialize, Deserializer};

pub fn as_u32<'de, D>(deserializer: D) -> Result<u32, D::Error>
where
D: Deserializer<'de>,
{
let float_data: f64 = Deserialize::deserialize(deserializer)?;

let u32_data = float_data as u32;

Ok(u32_data)
}

pub fn as_some_u32<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
where
D: Deserializer<'de>,
{
let float_data: Option<f64> = Deserialize::deserialize(deserializer)?;

match float_data {
Some(f) => return Ok(Some(f as u32)),

Check failure on line 26 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-ureq,rspotify/ureq-...

unneeded `return` statement

Check failure on line 26 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-reqwest,rspotify/re...

unneeded `return` statement
None => return Ok(None),

Check failure on line 27 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-ureq,rspotify/ureq-...

unneeded `return` statement

Check failure on line 27 in rspotify-model/src/data_type_patcher.rs

View workflow job for this annotation

GitHub Actions / Test and Lint for each Client (rspotify/cli,rspotify/env-file,rspotify/client-reqwest,rspotify/re...

unneeded `return` statement
}
}
}
6 changes: 6 additions & 0 deletions rspotify-model/src/image.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//! Image object
pub use crate::data_type_patcher::data_type_patcher::as_some_u32;

use serde::{Deserialize, Serialize};

/// Image object
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct Image {
// TODO: remove this statement after Spotify fix the [issue](https://github.com/ramsayleung/rspotify/issues/452)
#[serde(deserialize_with = "as_some_u32")]
pub height: Option<u32>,
pub url: String,
// TODO: remove this statement after Spotify fix the [issue](https://github.com/ramsayleung/rspotify/issues/452)
#[serde(deserialize_with = "as_some_u32")]
pub width: Option<u32>,
}
10 changes: 7 additions & 3 deletions rspotify-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod auth;
pub mod category;
pub mod context;
pub(crate) mod custom_serde;
pub mod data_type_patcher;
pub mod device;
pub mod enums;
pub mod error;
Expand All @@ -24,9 +25,10 @@ pub mod track;
pub mod user;

pub use {
album::*, artist::*, audio::*, auth::*, category::*, context::*, device::*, enums::*, error::*,
idtypes::*, image::*, offset::*, page::*, playing::*, playlist::*, recommend::*, search::*,
show::*, track::*, user::*,
album::*, artist::*, audio::*, auth::*, category::*, context::*,
data_type_patcher::data_type_patcher::as_u32, device::*, enums::*, error::*, idtypes::*,
image::*, offset::*, page::*, playing::*, playlist::*, recommend::*, search::*, show::*,
track::*, user::*,
};

use serde::{Deserialize, Serialize};
Expand All @@ -36,6 +38,8 @@ use serde::{Deserialize, Serialize};
pub struct Followers {
// This field will always set to null, as the Web API does not support it at the moment.
// pub href: Option<String>,
// TODO: remove this statement after Spotify fix the [issue](https://github.com/ramsayleung/rspotify/issues/452)
#[serde(deserialize_with = "as_u32")]
pub total: u32,
}

Expand Down

0 comments on commit 5d2ae3a

Please sign in to comment.