Add method to manually add artist metadata #85
@ -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>),
|
||||||
|
44
src/lib.rs
44
src/lib.rs
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user