Skip to content

Commit

Permalink
Allow for fuzzy parsing of image widths and heights (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog authored Feb 29, 2024
1 parent 3122d55 commit f9b7bbc
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
2 changes: 1 addition & 1 deletion crates/oxidize-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ publish = false

[dependencies]
chrono = { workspace = true }
diesel = { workspace = true }
diesel = { workspace = true, features = ["sqlite"] }
futures-util = { version = "0.3.28", default-features = false, features = ["sink", "alloc"] }
serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
60 changes: 58 additions & 2 deletions crates/oxidize-common/src/models/spotify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,62 @@
//! All Spotify API endpoint response object
//!
//! Copied under the MIT license from: <https://github.com/ramsayleung/rspotify>.

// Copied under the MIT license from: <https://github.com/ramsayleung/rspotify>.
//
// Copyright (c) 2015 Vincent Prouillet

use serde::de::{Deserialize, Deserializer, Error};

use serde_json::Number;

#[inline]
pub fn f64_to_u32(x: f64) -> Option<u32> {
let y = x as u32;

if y as f64 == x {
Some(y)
} else {
None
}
}

pub fn deserialize_option_u32<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
where
D: Deserializer<'de>,
{
let Some(number) = <Option<Number>>::deserialize(deserializer)? else {
return Ok(None);
};

if let Some(n) = number.as_u64() {
let Ok(n) = u32::try_from(n) else {
return Err(D::Error::custom(format_args!(
"Number {n} is out of numerical bounds 0-{}",
u32::MAX
)));
};

return Ok(Some(n));
}

if let Some(n) = number.as_i64() {
let Ok(n) = u32::try_from(n) else {
return Err(D::Error::custom(format_args!(
"Number {n} is out of numerical bounds 0-{}",
u32::MAX
)));
};

return Ok(Some(n));
}

if let Some(n) = number.as_f64().and_then(f64_to_u32) {
return Ok(Some(n));
}

Err(D::Error::custom(format_args!(
"Number {number} is not a valid u32"
)))
}

pub mod album;
pub mod artist;
Expand Down
17 changes: 17 additions & 0 deletions crates/oxidize-common/src/models/spotify/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,27 @@

use serde::{Deserialize, Serialize};

use super::deserialize_option_u32;

///[image object](https://developer.spotify.com/web-api/object-model/#image-object)
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Image {
#[serde(deserialize_with = "deserialize_option_u32")]
pub height: Option<u32>,
pub url: String,
#[serde(deserialize_with = "deserialize_option_u32")]
pub width: Option<u32>,
}

#[test]
fn test_deserialize_float_width_height() {
let json = r#"{"height": 640.0, "url": "https://i.scdn.co/image/ab67616d0000b273f3e3e3e3e3e3e3e3e3e3e3e3", "width": 640.0}"#;
let image: Image = serde_json::from_str(json).unwrap();
assert_eq!(image.height, Some(640));
assert_eq!(image.width, Some(640));

let json = r#"{"height": 640, "url": "https://i.scdn.co/image/ab67616d0000b273f3e3e3e3e3e3e3e3e3e3e3e3", "width": 640}"#;
let image: Image = serde_json::from_str(json).unwrap();
assert_eq!(image.height, Some(640));
assert_eq!(image.width, Some(640));
}

0 comments on commit f9b7bbc

Please sign in to comment.