Add method to manually add artist metadata #85

Merged
wojtek merged 16 commits from 55---add-method-to-manually-add-artist-metadata into main 2024-01-10 22:33:58 +01:00
2 changed files with 25 additions and 24 deletions
Showing only changes of commit 0a63ac4619 - Show all commits

View File

@ -47,7 +47,10 @@ enum ArtistCommand {
Delete(ArtistValue), Delete(ArtistValue),
#[structopt(name = "musicbrainz", about = "Edit the MusicBrainz URL of an artist")] #[structopt(name = "musicbrainz", about = "Edit the MusicBrainz URL of an artist")]
MusicBrainz(UrlCommand<SingleUrlValue>), MusicBrainz(UrlCommand<SingleUrlValue>),
#[structopt(name = "musicbutler", about = "Edit the MusicButler URL(s) of an artist")] #[structopt(
name = "musicbutler",
about = "Edit the MusicButler URL(s) of an artist"
)]
MusicButler(UrlCommand<MultiUrlValue>), MusicButler(UrlCommand<MultiUrlValue>),
#[structopt(about = "Edit the Bandcamp URL(s) of an artist")] #[structopt(about = "Edit the Bandcamp URL(s) of an artist")]
Bandcamp(UrlCommand<MultiUrlValue>), Bandcamp(UrlCommand<MultiUrlValue>),

View File

@ -6,7 +6,7 @@ pub mod library;
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fmt::{self, Debug}, fmt::{self, Debug, Display},
iter::Peekable, iter::Peekable,
mem, mem,
}; };
@ -42,7 +42,7 @@ struct InvalidUrlError {
url: String, url: String,
} }
impl fmt::Display for InvalidUrlError { impl Display for InvalidUrlError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid url of type {:?}: {}", self.url_type, self.url) write!(f, "invalid url of type {:?}: {}", self.url_type, self.url)
} }
@ -88,7 +88,7 @@ impl TryFrom<&str> for MusicBrainz {
} }
} }
impl fmt::Display for MusicBrainz { impl Display for MusicBrainz {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0) write!(f, "{}", self.0)
} }
@ -232,7 +232,7 @@ impl TryFrom<&str> for Qobuz {
} }
} }
impl fmt::Display for Qobuz { impl Display for Qobuz {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0) write!(f, "{}", self.0)
} }
@ -344,7 +344,7 @@ impl ArtistId {
} }
} }
impl fmt::Display for ArtistId { impl Display for ArtistId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name) write!(f, "{}", self.name)
} }
@ -431,10 +431,7 @@ impl Artist {
} }
} }
fn add_unique_url< fn add_unique_url<S: AsRef<str>, T: for<'a> TryFrom<&'a str, Error = Error> + Eq + Display>(
S: AsRef<str>,
T: for<'a> TryFrom<&'a str, Error = Error> + Eq + fmt::Display,
>(
container: &mut Option<T>, container: &mut Option<T>,
url: S, url: S,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -643,7 +640,7 @@ pub enum Error {
InvalidUrlError(String), InvalidUrlError(String),
} }
impl fmt::Display for Error { impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Self::CollectionError(ref s) => write!(f, "failed to read/write the collection: {s}"), Self::CollectionError(ref s) => write!(f, "failed to read/write the collection: {s}"),
@ -832,15 +829,16 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
} }
} }
pub fn new_artist<ID: AsRef<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> { pub fn new_artist<ID: Into<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> {
if let Ok(artist) = self.get_artist_or_err(artist_id.as_ref()) { let artist_id: ArtistId = artist_id.into();
if let Ok(artist) = self.get_artist_or_err(&artist_id) {
return Err(Error::CollectionError(format!( return Err(Error::CollectionError(format!(
"artist '{}' is already in the collection", "artist '{}' is already in the collection",
artist.id artist.id
))); )));
} }
let new_artist = vec![Artist::new(artist_id.as_ref().clone())]; let new_artist = vec![Artist::new(artist_id)];
let collection = mem::take(&mut self.collection); let collection = mem::take(&mut self.collection);
self.collection = Self::merge(collection, new_artist); self.collection = Self::merge(collection, new_artist);
@ -1090,9 +1088,9 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let actual_err = music_hoard.new_artist(&artist_id).unwrap_err(); let actual_err = music_hoard.new_artist(artist_id.clone()).unwrap_err();
let expected_err = Error::CollectionError(String::from( let expected_err = Error::CollectionError(String::from(
"artist 'an artist' is already in the collection", "artist 'an artist' is already in the collection",
)); ));
@ -1115,7 +1113,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Option<MusicBrainz> = None; let mut expected: Option<MusicBrainz> = None;
assert_eq!(music_hoard.collection[0].properties.musicbrainz, expected); assert_eq!(music_hoard.collection[0].properties.musicbrainz, expected);
@ -1186,7 +1184,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Option<MusicBrainz> = None; let mut expected: Option<MusicBrainz> = None;
assert_eq!(music_hoard.collection[0].properties.musicbrainz, expected); assert_eq!(music_hoard.collection[0].properties.musicbrainz, expected);
@ -1241,7 +1239,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Vec<MusicButler> = vec![]; let mut expected: Vec<MusicButler> = vec![];
assert_eq!(music_hoard.collection[0].properties.musicbutler, expected); assert_eq!(music_hoard.collection[0].properties.musicbutler, expected);
@ -1371,7 +1369,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Vec<MusicButler> = vec![]; let mut expected: Vec<MusicButler> = vec![];
assert_eq!(music_hoard.collection[0].properties.musicbutler, expected); assert_eq!(music_hoard.collection[0].properties.musicbutler, expected);
@ -1434,7 +1432,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Vec<Bandcamp> = vec![]; let mut expected: Vec<Bandcamp> = vec![];
assert_eq!(music_hoard.collection[0].properties.bandcamp, expected); assert_eq!(music_hoard.collection[0].properties.bandcamp, expected);
@ -1564,7 +1562,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Vec<Bandcamp> = vec![]; let mut expected: Vec<Bandcamp> = vec![];
assert_eq!(music_hoard.collection[0].properties.bandcamp, expected); assert_eq!(music_hoard.collection[0].properties.bandcamp, expected);
@ -1627,7 +1625,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Option<Qobuz> = None; let mut expected: Option<Qobuz> = None;
assert_eq!(music_hoard.collection[0].properties.qobuz, expected); assert_eq!(music_hoard.collection[0].properties.qobuz, expected);
@ -1678,7 +1676,7 @@ mod tests {
let artist_id_2 = ArtistId::new("another artist"); let artist_id_2 = ArtistId::new("another artist");
let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None); let mut music_hoard = MusicHoard::<NoLibrary, NoDatabase>::new(None, None);
assert!(music_hoard.new_artist(&artist_id).is_ok()); assert!(music_hoard.new_artist(artist_id.clone()).is_ok());
let mut expected: Option<Qobuz> = None; let mut expected: Option<Qobuz> = None;
assert_eq!(music_hoard.collection[0].properties.qobuz, expected); assert_eq!(music_hoard.collection[0].properties.qobuz, expected);