Add code for modifying musicbutler entries

This commit is contained in:
Wojciech Kozlowski 2024-01-08 18:54:03 +01:00
parent bbab89d25f
commit 3ea68d2935
2 changed files with 119 additions and 29 deletions

View File

@ -73,18 +73,18 @@ struct MultiUrlValue {
} }
macro_rules! url_command_dispatch { macro_rules! url_command_dispatch {
($command:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident) => { ($cmd:ident, $mh:ident, $add:ident, $remove:ident, $set:ident, $clear:ident, $url:ident) => {
match $command { match $cmd {
UrlCommand::Add(single_url_value) => { UrlCommand::Add(url_value) => {
$mh.$add(ArtistId::new(single_url_value.artist), single_url_value.url) $mh.$add(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to add URL(s)"); .expect("failed to add URL(s)");
} }
UrlCommand::Remove(single_url_value) => { UrlCommand::Remove(url_value) => {
$mh.$remove(ArtistId::new(single_url_value.artist), single_url_value.url) $mh.$remove(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to remove URL(s)"); .expect("failed to remove URL(s)");
} }
UrlCommand::Set(single_url_value) => { UrlCommand::Set(url_value) => {
$mh.$set(ArtistId::new(single_url_value.artist), single_url_value.url) $mh.$set(ArtistId::new(url_value.artist), url_value.$url)
.expect("failed to set URL(s)"); .expect("failed to set URL(s)");
} }
UrlCommand::Clear(artist_value) => { UrlCommand::Clear(artist_value) => {
@ -114,24 +114,18 @@ impl ArtistCommand {
add_musicbrainz_url, add_musicbrainz_url,
remove_musicbrainz_url, remove_musicbrainz_url,
set_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) => { ArtistCommand::Bandcamp(url_command) => {
match url_command { match url_command {
UrlCommand::Add(_) => { UrlCommand::Add(_) => {

View File

@ -375,6 +375,65 @@ impl Artist {
self.properties.musicbrainz = None; self.properties.musicbrainz = None;
Ok(()) 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 { impl PartialOrd for Artist {
@ -663,6 +722,41 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
.clear_musicbrainz_url() .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]) { fn sort(collection: &mut [Artist]) {
collection.sort_unstable(); collection.sort_unstable();
for artist in collection.iter_mut() { for artist in collection.iter_mut() {
@ -745,8 +839,10 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
} }
fn get_artist_or_err(&mut self, artist_id: &ArtistId) -> Result<&mut Artist, Error> { 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); self.collection
artist_opt.ok_or_else(|| { .iter_mut()
.find(|a| &a.id == artist_id)
.ok_or_else(|| {
Error::CollectionError(format!("artist '{}' is not in the collection", artist_id)) Error::CollectionError(format!("artist '{}' is not in the collection", artist_id))
}) })
} }