Add method to manually add artist metadata #85
@ -73,18 +73,18 @@ struct MultiUrlValue {
|
||||
}
|
||||
|
||||
macro_rules! url_command_dispatch {
|
||||
($command:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident) => {
|
||||
match $command {
|
||||
UrlCommand::Add(single_url_value) => {
|
||||
$mh.$add(ArtistId::new(single_url_value.artist), single_url_value.url)
|
||||
($cmd:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident, $url:ident) => {
|
||||
match $cmd {
|
||||
UrlCommand::Add(url_value) => {
|
||||
$mh.$add(ArtistId::new(url_value.artist), url_value.$url)
|
||||
.expect("failed to add URL(s)");
|
||||
}
|
||||
UrlCommand::Remove(single_url_value) => {
|
||||
$mh.$remove(ArtistId::new(single_url_value.artist), single_url_value.url)
|
||||
UrlCommand::Remove(url_value) => {
|
||||
$mh.$remove(ArtistId::new(url_value.artist), url_value.$url)
|
||||
.expect("failed to remove URL(s)");
|
||||
}
|
||||
UrlCommand::Set(single_url_value) => {
|
||||
$mh.$set(ArtistId::new(single_url_value.artist), single_url_value.url)
|
||||
UrlCommand::Set(url_value) => {
|
||||
$mh.$set(ArtistId::new(url_value.artist), url_value.$url)
|
||||
.expect("failed to set URL(s)");
|
||||
}
|
||||
UrlCommand::Clear(artist_value) => {
|
||||
@ -114,24 +114,18 @@ impl ArtistCommand {
|
||||
add_musicbrainz_url,
|
||||
remove_musicbrainz_url,
|
||||
set_musicbrainz_url,
|
||||
clear_musicbrainz_url
|
||||
clear_musicbrainz_url,
|
||||
url
|
||||
),
|
||||
ArtistCommand::MusicButler(url_command) => url_command_dispatch!(
|
||||
url_command,
|
||||
music_hoard,
|
||||
add_musicbutler_urls,
|
||||
remove_musicbutler_urls,
|
||||
set_musicbutler_urls,
|
||||
clear_musicbutler_urls,
|
||||
urls
|
||||
),
|
||||
ArtistCommand::MusicButler(url_command) => {
|
||||
match url_command {
|
||||
UrlCommand::Add(_) => {
|
||||
// Add URL.
|
||||
}
|
||||
UrlCommand::Remove(_) => {
|
||||
// Remove URL if it exists.
|
||||
}
|
||||
UrlCommand::Set(_) => {
|
||||
// Set the URLs regardless of previous (if any) value.
|
||||
}
|
||||
UrlCommand::Clear(_) => {
|
||||
// Remove the URLs.
|
||||
}
|
||||
}
|
||||
}
|
||||
ArtistCommand::Bandcamp(url_command) => {
|
||||
match url_command {
|
||||
UrlCommand::Add(_) => {
|
||||
|
104
src/lib.rs
104
src/lib.rs
@ -375,6 +375,65 @@ impl Artist {
|
||||
self.properties.musicbrainz = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
|
||||
// Convert into URLs first to facilitate later comparison.
|
||||
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
|
||||
let mut urls = urls?;
|
||||
|
||||
// Do not check and insert. First check if any of the provided URLs already exist so that
|
||||
// the vector remains unchanged in case of failure.
|
||||
let overlap: Vec<&MusicButler> = urls
|
||||
.iter()
|
||||
.filter(|url| self.properties.musicbutler.contains(url))
|
||||
.collect();
|
||||
if !overlap.is_empty() {
|
||||
return Err(Error::CollectionError(format!(
|
||||
"artist '{}' already has these MusicButler URL(s): {:?}",
|
||||
self.id, overlap
|
||||
)));
|
||||
}
|
||||
|
||||
self.properties.musicbutler.append(&mut urls);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
|
||||
// Convert into URLs first to facilitate later comparison.
|
||||
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
|
||||
let urls = urls?;
|
||||
|
||||
// Do not check and insert. First check if any of the provided URLs already exist so that
|
||||
// the vector remains unchanged in case of failure.
|
||||
let difference: Vec<&MusicButler> = urls
|
||||
.iter()
|
||||
.filter(|url| !self.properties.musicbutler.contains(url))
|
||||
.collect();
|
||||
if !difference.is_empty() {
|
||||
return Err(Error::CollectionError(format!(
|
||||
"artist '{}' does not have these MusicButler URL(s): {:?}",
|
||||
self.id, difference
|
||||
)));
|
||||
}
|
||||
|
||||
let musicbutler = mem::take(&mut self.properties.musicbutler);
|
||||
self.properties.musicbutler = musicbutler
|
||||
.into_iter()
|
||||
.filter(|url| !urls.contains(url))
|
||||
.collect();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_musicbutler_urls<S: AsRef<str>>(&mut self, urls: Vec<S>) -> Result<(), Error> {
|
||||
let urls: Result<Vec<MusicButler>, Error> = urls.iter().map(MusicButler::new).collect();
|
||||
self.properties.musicbutler = urls?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn clear_musicbutler_urls(&mut self) -> Result<(), Error> {
|
||||
self.properties.musicbutler.clear();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Artist {
|
||||
@ -663,6 +722,41 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||
.clear_musicbrainz_url()
|
||||
}
|
||||
|
||||
pub fn add_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
urls: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.get_artist_or_err(artist_id.as_ref())?
|
||||
.add_musicbutler_urls(urls)
|
||||
}
|
||||
|
||||
pub fn remove_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
urls: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.get_artist_or_err(artist_id.as_ref())?
|
||||
.remove_musicbutler_urls(urls)
|
||||
}
|
||||
|
||||
pub fn set_musicbutler_urls<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
urls: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.get_artist_or_err(artist_id.as_ref())?
|
||||
.set_musicbutler_urls(urls)
|
||||
}
|
||||
|
||||
pub fn clear_musicbutler_urls<ID: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
) -> Result<(), Error> {
|
||||
self.get_artist_or_err(artist_id.as_ref())?
|
||||
.clear_musicbutler_urls()
|
||||
}
|
||||
|
||||
fn sort(collection: &mut [Artist]) {
|
||||
collection.sort_unstable();
|
||||
for artist in collection.iter_mut() {
|
||||
@ -745,10 +839,12 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||
}
|
||||
|
||||
fn get_artist_or_err(&mut self, artist_id: &ArtistId) -> Result<&mut Artist, Error> {
|
||||
let artist_opt = self.collection.iter_mut().find(|a| &a.id == artist_id);
|
||||
artist_opt.ok_or_else(|| {
|
||||
Error::CollectionError(format!("artist '{}' is not in the collection", artist_id))
|
||||
})
|
||||
self.collection
|
||||
.iter_mut()
|
||||
.find(|a| &a.id == artist_id)
|
||||
.ok_or_else(|| {
|
||||
Error::CollectionError(format!("artist '{}' is not in the collection", artist_id))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user