fix(album): use dedicated tolerant AlbumAward struct instead of mutating PageArtistAward
Previous attempt loosened PageArtistAward (id u64 -> Option<u64>,
awarded_at custom deserializer) to accept /album/get's inconsistent
award shape. That rippled into /artist/page consumers, which the user
rightly called out ('no eliminar lo que ya funcionaba, adaptar pues').
Restores PageArtistAward to its original shape (id: u64, name: String,
awarded_at: Option<String>) and introduces a parallel AlbumAward type
used only on DiscoverAlbum and Album. AlbumAward tolerates missing id,
accepts awarded_at as int or string, and never fails deserialization
of the parent payload. /artist/page keeps its strict contract.
cc
This commit is contained in:
3 files changed
+37
-17
No files matched your search
@@ -232,7 +232,7 @@ pub struct Album {
|
||||
pub description: Option<String>,
|
||||
/// Editorial awards attached to the album.
|
||||
#[serde(default)]
|
||||
pub awards: Option<Vec<PageArtistAward>>,
|
||||
pub awards: Option<Vec<AlbumAward>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -965,13 +965,22 @@ pub struct PageArtistRights {
|
||||
pub struct PageArtistAward {
|
||||
pub id: u64,
|
||||
pub name: String,
|
||||
/// Qobuz returns this either as "YYYY-MM-DD" or a Unix timestamp
|
||||
/// integer depending on the endpoint — accept both.
|
||||
#[serde(default, deserialize_with = "deserialize_awarded_at")]
|
||||
pub awarded_at: Option<String>,
|
||||
}
|
||||
|
||||
fn deserialize_awarded_at<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||
/// Tolerant award struct used in Album responses where Qobuz is
|
||||
/// inconsistent about optional id and awarded_at types.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct AlbumAward {
|
||||
#[serde(default)]
|
||||
pub id: Option<u64>,
|
||||
#[serde(default)]
|
||||
pub name: String,
|
||||
#[serde(default, deserialize_with = "deserialize_album_awarded_at")]
|
||||
pub awarded_at: Option<String>,
|
||||
}
|
||||
|
||||
fn deserialize_album_awarded_at<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
@@ -979,8 +988,7 @@ where
|
||||
Ok(match value {
|
||||
Some(serde_json::Value::String(s)) => Some(s),
|
||||
Some(serde_json::Value::Number(n)) => Some(n.to_string()),
|
||||
Some(serde_json::Value::Null) | None => None,
|
||||
Some(_) => None,
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user