Reduc implementation to mbid

This commit is contained in:
Wojciech Kozlowski 2024-08-29 13:18:47 +02:00
parent f82a6376e0
commit b12516dccc
2 changed files with 37 additions and 97 deletions

View File

@ -6,10 +6,10 @@ use crate::{
core::collection::{
album::{Album, AlbumDate, AlbumId, AlbumSeq},
artist::{Artist, ArtistId},
musicbrainz::{MbAlbumRef, MbArtistRef},
Collection, Error as CollectionError,
Collection,
},
external::database::serde::common::{SerdeAlbumPrimaryType, SerdeAlbumSecondaryType},
interface::musicbrainz::{Mbid, MbidError},
};
#[derive(Debug, Deserialize)]
@ -31,7 +31,7 @@ impl From<DeserializeDatabase> for Collection {
pub struct DeserializeArtist {
name: String,
sort: Option<String>,
musicbrainz: Option<DeserializeMbArtistRef>,
musicbrainz: Option<DeserializeMbid>,
properties: HashMap<String, Vec<String>>,
albums: Vec<DeserializeAlbum>,
}
@ -40,24 +40,24 @@ pub struct DeserializeArtist {
pub struct DeserializeAlbum {
title: String,
seq: u8,
musicbrainz: Option<DeserializeMbAlbumRef>,
musicbrainz: Option<DeserializeMbid>,
primary_type: Option<SerdeAlbumPrimaryType>,
secondary_types: Vec<SerdeAlbumSecondaryType>,
}
#[derive(Clone, Debug)]
pub struct DeserializeMbArtistRef(MbArtistRef);
pub struct DeserializeMbid(Mbid);
impl From<DeserializeMbArtistRef> for MbArtistRef {
fn from(value: DeserializeMbArtistRef) -> Self {
impl From<DeserializeMbid> for Mbid {
fn from(value: DeserializeMbid) -> Self {
value.0
}
}
struct DeserializeMbArtistRefVisitor;
struct DeserializeMbidVisitor;
impl<'de> Visitor<'de> for DeserializeMbArtistRefVisitor {
type Value = DeserializeMbArtistRef;
impl<'de> Visitor<'de> for DeserializeMbidVisitor {
type Value = DeserializeMbid;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid MusicBrainz identifier")
@ -67,55 +67,19 @@ impl<'de> Visitor<'de> for DeserializeMbArtistRefVisitor {
where
E: serde::de::Error,
{
Ok(DeserializeMbArtistRef(
MbArtistRef::from_uuid_str(v).map_err(|e: CollectionError| E::custom(e.to_string()))?,
Ok(DeserializeMbid(
v.try_into()
.map_err(|e: MbidError| E::custom(e.to_string()))?,
))
}
}
impl<'de> Deserialize<'de> for DeserializeMbArtistRef {
impl<'de> Deserialize<'de> for DeserializeMbid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(DeserializeMbArtistRefVisitor)
}
}
#[derive(Clone, Debug)]
pub struct DeserializeMbAlbumRef(MbAlbumRef);
impl From<DeserializeMbAlbumRef> for MbAlbumRef {
fn from(value: DeserializeMbAlbumRef) -> Self {
value.0
}
}
struct DeserializeMbAlbumRefVisitor;
impl<'de> Visitor<'de> for DeserializeMbAlbumRefVisitor {
type Value = DeserializeMbAlbumRef;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid MusicBrainz identifier")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(DeserializeMbAlbumRef(
MbAlbumRef::from_uuid_str(v).map_err(|e: CollectionError| E::custom(e.to_string()))?,
))
}
}
impl<'de> Deserialize<'de> for DeserializeMbAlbumRef {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(DeserializeMbAlbumRefVisitor)
deserializer.deserialize_str(DeserializeMbidVisitor)
}
}
@ -124,7 +88,7 @@ impl From<DeserializeArtist> for Artist {
Artist {
id: ArtistId::new(artist.name),
sort: artist.sort.map(ArtistId::new),
musicbrainz: artist.musicbrainz.map(Into::into),
musicbrainz: artist.musicbrainz.map(Into::<Mbid>::into).map(Into::into),
properties: artist.properties,
albums: artist.albums.into_iter().map(Into::into).collect(),
}
@ -137,7 +101,7 @@ impl From<DeserializeAlbum> for Album {
id: AlbumId { title: album.title },
date: AlbumDate::default(),
seq: AlbumSeq(album.seq),
musicbrainz: album.musicbrainz.map(Into::into),
musicbrainz: album.musicbrainz.map(Into::<Mbid>::into).map(Into::into),
primary_type: album.primary_type.map(Into::into),
secondary_types: album.secondary_types.into_iter().map(Into::into).collect(),
tracks: vec![],
@ -150,35 +114,17 @@ mod tests {
use super::*;
#[test]
fn deserialize_mb_artist_ref() {
fn deserialize_mbid() {
let mbid = "\"d368baa8-21ca-4759-9731-0b2753071ad8\"";
let mbref: DeserializeMbArtistRef = serde_json::from_str(mbid).unwrap();
let mbref: MbArtistRef = mbref.into();
let mbid: DeserializeMbid = serde_json::from_str(mbid).unwrap();
let mbid: Mbid = mbid.into();
assert_eq!(
mbref,
MbArtistRef::from_uuid_str("d368baa8-21ca-4759-9731-0b2753071ad8").unwrap()
mbid,
"d368baa8-21ca-4759-9731-0b2753071ad8".try_into().unwrap()
);
let mbid = "null";
let result: Result<DeserializeMbArtistRef, _> = serde_json::from_str(mbid);
assert!(result
.unwrap_err()
.to_string()
.contains("a valid MusicBrainz identifier"));
}
#[test]
fn deserialize_mb_album_ref() {
let mbid = "\"d368baa8-21ca-4759-9731-0b2753071ad8\"";
let mbref: DeserializeMbAlbumRef = serde_json::from_str(mbid).unwrap();
let mbref: MbAlbumRef = mbref.into();
assert_eq!(
mbref,
MbAlbumRef::from_uuid_str("d368baa8-21ca-4759-9731-0b2753071ad8").unwrap()
);
let mbid = "null";
let result: Result<DeserializeMbAlbumRef, _> = serde_json::from_str(mbid);
let result: Result<DeserializeMbid, _> = serde_json::from_str(mbid);
assert!(result
.unwrap_err()
.to_string()

View File

@ -3,9 +3,9 @@ use std::collections::BTreeMap;
use serde::Serialize;
use crate::{
collection::musicbrainz::{MbAlbumRef, MbArtistRef},
core::collection::{album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, Collection},
external::database::serde::common::{SerdeAlbumPrimaryType, SerdeAlbumSecondaryType},
interface::musicbrainz::Mbid,
};
#[derive(Debug, Serialize)]
@ -23,7 +23,7 @@ impl<'a> From<&'a Collection> for SerializeDatabase<'a> {
pub struct SerializeArtist<'a> {
name: &'a str,
sort: Option<&'a str>,
musicbrainz: Option<SerializeMbArtistRef<'a>>,
musicbrainz: Option<SerializeMbid<'a>>,
properties: BTreeMap<&'a str, &'a Vec<String>>,
albums: Vec<SerializeAlbum<'a>>,
}
@ -32,32 +32,20 @@ pub struct SerializeArtist<'a> {
pub struct SerializeAlbum<'a> {
title: &'a str,
seq: u8,
musicbrainz: Option<SerializeMbAlbumRef<'a>>,
musicbrainz: Option<SerializeMbid<'a>>,
primary_type: Option<SerdeAlbumPrimaryType>,
secondary_types: Vec<SerdeAlbumSecondaryType>,
}
#[derive(Clone, Debug)]
pub struct SerializeMbArtistRef<'a>(&'a MbArtistRef);
pub struct SerializeMbid<'a>(&'a Mbid);
impl<'a> Serialize for SerializeMbArtistRef<'a> {
impl<'a> Serialize for SerializeMbid<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.0.mbid().uuid().as_hyphenated().to_string())
}
}
#[derive(Clone, Debug)]
pub struct SerializeMbAlbumRef<'a>(&'a MbAlbumRef);
impl<'a> Serialize for SerializeMbAlbumRef<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.0.mbid().uuid().as_hyphenated().to_string())
serializer.serialize_str(&self.0.uuid().as_hyphenated().to_string())
}
}
@ -66,7 +54,10 @@ impl<'a> From<&'a Artist> for SerializeArtist<'a> {
SerializeArtist {
name: &artist.id.name,
sort: artist.sort.as_ref().map(|id| id.name.as_ref()),
musicbrainz: artist.musicbrainz.as_ref().map(SerializeMbArtistRef),
musicbrainz: artist
.musicbrainz
.as_ref()
.map(|mbref| SerializeMbid(mbref.mbid())),
properties: artist
.properties
.iter()
@ -82,7 +73,10 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> {
SerializeAlbum {
title: &album.id.title,
seq: album.seq.0,
musicbrainz: album.musicbrainz.as_ref().map(SerializeMbAlbumRef),
musicbrainz: album
.musicbrainz
.as_ref()
.map(|mbref| SerializeMbid(mbref.mbid())),
primary_type: album.primary_type.map(Into::into),
secondary_types: album
.secondary_types