diff --git a/src/bin/musichoard-edit.rs b/src/bin/musichoard-edit.rs index f589b12..8d06e32 100644 --- a/src/bin/musichoard-edit.rs +++ b/src/bin/musichoard-edit.rs @@ -5,7 +5,7 @@ use structopt::{clap::AppSettings, StructOpt}; use musichoard::{ collection::{album::AlbumId, artist::ArtistId}, database::json::{backend::JsonDatabaseFileBackend, JsonDatabase}, - MusicHoard, MusicHoardBuilder, NoLibrary, + IMusicHoardDatabase, MusicHoard, MusicHoardBuilder, NoLibrary, }; type MH = MusicHoard, NoLibrary>; diff --git a/src/core/musichoard/builder.rs b/src/core/musichoard/builder.rs index 3a99805..0a9f53e 100644 --- a/src/core/musichoard/builder.rs +++ b/src/core/musichoard/builder.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::{ core::{ interface::{database::IDatabase, library::ILibrary}, - musichoard::{MusicHoard, NoDatabase, NoLibrary}, + musichoard::{database::IMusicHoardDatabase, MusicHoard, NoDatabase, NoLibrary}, }, Error, }; diff --git a/src/core/musichoard/database.rs b/src/core/musichoard/database.rs index 19f26e0..d9aa6c0 100644 --- a/src/core/musichoard/database.rs +++ b/src/core/musichoard/database.rs @@ -9,16 +9,66 @@ use crate::core::{ musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase}, }; -impl MusicHoard { - pub fn commit(&mut self) -> Result<(), Error> { - self.collection = self.pre_commit.clone(); - Ok(()) - } +pub trait IMusicHoardDatabase { + fn reload_database(&mut self) -> Result<(), Error>; + + fn add_artist>(&mut self, artist_id: IntoId) -> Result<(), Error>; + fn remove_artist>(&mut self, artist_id: Id) -> Result<(), Error>; + + fn set_artist_sort, IntoId: Into>( + &mut self, + artist_id: Id, + artist_sort: IntoId, + ) -> Result<(), Error>; + fn clear_artist_sort>(&mut self, artist_id: Id) -> Result<(), Error>; + + fn set_artist_musicbrainz, S: AsRef>( + &mut self, + artist_id: Id, + url: S, + ) -> Result<(), Error>; + fn clear_artist_musicbrainz>(&mut self, artist_id: Id) + -> Result<(), Error>; + + fn add_to_artist_property, S: AsRef + Into>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error>; + fn remove_from_artist_property, S: AsRef>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error>; + fn set_artist_property, S: AsRef + Into>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error>; + fn clear_artist_property, S: AsRef>( + &mut self, + artist_id: Id, + property: S, + ) -> Result<(), Error>; + + fn set_album_seq, AlbumIdRef: AsRef>( + &mut self, + artist_id: ArtistIdRef, + album_id: AlbumIdRef, + seq: u8, + ) -> Result<(), Error>; + fn clear_album_seq, AlbumIdRef: AsRef>( + &mut self, + artist_id: ArtistIdRef, + album_id: AlbumIdRef, + ) -> Result<(), Error>; } -impl MusicHoard { - /// Load the database and merge with the in-memory collection. - pub fn reload_database(&mut self) -> Result<(), Error> { +impl IMusicHoardDatabase for MusicHoard { + fn reload_database(&mut self) -> Result<(), Error> { self.database_cache = self.database.load()?; Self::sort_albums_and_tracks(self.database_cache.iter_mut()); @@ -28,7 +78,146 @@ impl MusicHoard { Ok(()) } - pub fn commit(&mut self) -> Result<(), Error> { + fn add_artist>(&mut self, artist_id: IntoId) -> Result<(), Error> { + let artist_id: ArtistId = artist_id.into(); + + self.update_collection(|collection| { + if Self::get_artist(collection, &artist_id).is_none() { + collection.push(Artist::new(artist_id)); + Self::sort_artists(collection); + } + }) + } + + fn remove_artist>(&mut self, artist_id: Id) -> Result<(), Error> { + self.update_collection(|collection| { + let index_opt = collection.iter().position(|a| &a.id == artist_id.as_ref()); + if let Some(index) = index_opt { + collection.remove(index); + } + }) + } + + fn set_artist_sort, IntoId: Into>( + &mut self, + artist_id: Id, + artist_sort: IntoId, + ) -> Result<(), Error> { + self.update_artist_and( + artist_id.as_ref(), + |artist| artist.set_sort_key(artist_sort), + |collection| Self::sort_artists(collection), + ) + } + + fn clear_artist_sort>(&mut self, artist_id: Id) -> Result<(), Error> { + self.update_artist_and( + artist_id.as_ref(), + |artist| artist.clear_sort_key(), + |collection| Self::sort_artists(collection), + ) + } + + fn set_artist_musicbrainz, S: AsRef>( + &mut self, + artist_id: Id, + url: S, + ) -> Result<(), Error> { + let mb = MusicBrainzUrl::artist_from_str(url)?; + self.update_artist(artist_id.as_ref(), |artist| artist.set_musicbrainz_url(mb)) + } + + fn clear_artist_musicbrainz>( + &mut self, + artist_id: Id, + ) -> Result<(), Error> { + self.update_artist(artist_id.as_ref(), |artist| artist.clear_musicbrainz_url()) + } + + fn add_to_artist_property, S: AsRef + Into>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error> { + self.update_artist(artist_id.as_ref(), |artist| { + artist.add_to_property(property, values) + }) + } + + fn remove_from_artist_property, S: AsRef>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error> { + self.update_artist(artist_id.as_ref(), |artist| { + artist.remove_from_property(property, values) + }) + } + + fn set_artist_property, S: AsRef + Into>( + &mut self, + artist_id: Id, + property: S, + values: Vec, + ) -> Result<(), Error> { + self.update_artist(artist_id.as_ref(), |artist| { + artist.set_property(property, values) + }) + } + + fn clear_artist_property, S: AsRef>( + &mut self, + artist_id: Id, + property: S, + ) -> Result<(), Error> { + self.update_artist(artist_id.as_ref(), |artist| artist.clear_property(property)) + } + + fn set_album_seq, AlbumIdRef: AsRef>( + &mut self, + artist_id: ArtistIdRef, + album_id: AlbumIdRef, + seq: u8, + ) -> Result<(), Error> { + self.update_album_and( + artist_id.as_ref(), + album_id.as_ref(), + |album| album.set_seq(AlbumSeq(seq)), + |artist| artist.albums.sort_unstable(), + |_| {}, + ) + } + + fn clear_album_seq, AlbumIdRef: AsRef>( + &mut self, + artist_id: ArtistIdRef, + album_id: AlbumIdRef, + ) -> Result<(), Error> { + self.update_album_and( + artist_id.as_ref(), + album_id.as_ref(), + |album| album.clear_seq(), + |artist| artist.albums.sort_unstable(), + |_| {}, + ) + } +} + +pub trait IMusicHoardDatabasePrivate { + fn commit(&mut self) -> Result<(), Error>; +} + +impl IMusicHoardDatabasePrivate for MusicHoard { + fn commit(&mut self) -> Result<(), Error> { + self.collection = self.pre_commit.clone(); + Ok(()) + } +} + +impl IMusicHoardDatabasePrivate for MusicHoard { + fn commit(&mut self) -> Result<(), Error> { if self.collection != self.pre_commit { if let Err(err) = self.database.save(&self.pre_commit) { self.pre_commit = self.collection.clone(); @@ -38,7 +227,9 @@ impl MusicHoard { } Ok(()) } +} +impl MusicHoard { fn update_collection(&mut self, fn_coll: FnColl) -> Result<(), Error> where FnColl: FnOnce(&mut Collection), @@ -92,132 +283,6 @@ impl MusicHoard { fn_artist(artist); self.update_collection(fn_coll) } - - pub fn add_artist>(&mut self, artist_id: IntoId) -> Result<(), Error> { - let artist_id: ArtistId = artist_id.into(); - - self.update_collection(|collection| { - if Self::get_artist(collection, &artist_id).is_none() { - collection.push(Artist::new(artist_id)); - Self::sort_artists(collection); - } - }) - } - - pub fn remove_artist>(&mut self, artist_id: Id) -> Result<(), Error> { - self.update_collection(|collection| { - let index_opt = collection.iter().position(|a| &a.id == artist_id.as_ref()); - if let Some(index) = index_opt { - collection.remove(index); - } - }) - } - - pub fn set_artist_sort, IntoId: Into>( - &mut self, - artist_id: Id, - artist_sort: IntoId, - ) -> Result<(), Error> { - self.update_artist_and( - artist_id.as_ref(), - |artist| artist.set_sort_key(artist_sort), - |collection| Self::sort_artists(collection), - ) - } - - pub fn clear_artist_sort>(&mut self, artist_id: Id) -> Result<(), Error> { - self.update_artist_and( - artist_id.as_ref(), - |artist| artist.clear_sort_key(), - |collection| Self::sort_artists(collection), - ) - } - - pub fn set_artist_musicbrainz, S: AsRef>( - &mut self, - artist_id: Id, - url: S, - ) -> Result<(), Error> { - let mb = MusicBrainzUrl::artist_from_str(url)?; - self.update_artist(artist_id.as_ref(), |artist| artist.set_musicbrainz_url(mb)) - } - - pub fn clear_artist_musicbrainz>( - &mut self, - artist_id: Id, - ) -> Result<(), Error> { - self.update_artist(artist_id.as_ref(), |artist| artist.clear_musicbrainz_url()) - } - - pub fn add_to_artist_property, S: AsRef + Into>( - &mut self, - artist_id: Id, - property: S, - values: Vec, - ) -> Result<(), Error> { - self.update_artist(artist_id.as_ref(), |artist| { - artist.add_to_property(property, values) - }) - } - - pub fn remove_from_artist_property, S: AsRef>( - &mut self, - artist_id: Id, - property: S, - values: Vec, - ) -> Result<(), Error> { - self.update_artist(artist_id.as_ref(), |artist| { - artist.remove_from_property(property, values) - }) - } - - pub fn set_artist_property, S: AsRef + Into>( - &mut self, - artist_id: Id, - property: S, - values: Vec, - ) -> Result<(), Error> { - self.update_artist(artist_id.as_ref(), |artist| { - artist.set_property(property, values) - }) - } - - pub fn clear_artist_property, S: AsRef>( - &mut self, - artist_id: Id, - property: S, - ) -> Result<(), Error> { - self.update_artist(artist_id.as_ref(), |artist| artist.clear_property(property)) - } - - pub fn set_album_seq, AlbumIdRef: AsRef>( - &mut self, - artist_id: ArtistIdRef, - album_id: AlbumIdRef, - seq: u8, - ) -> Result<(), Error> { - self.update_album_and( - artist_id.as_ref(), - album_id.as_ref(), - |album| album.set_seq(AlbumSeq(seq)), - |artist| artist.albums.sort_unstable(), - |_| {}, - ) - } - - pub fn clear_album_seq, AlbumIdRef: AsRef>( - &mut self, - artist_id: ArtistIdRef, - album_id: AlbumIdRef, - ) -> Result<(), Error> { - self.update_album_and( - artist_id.as_ref(), - album_id.as_ref(), - |album| album.clear_seq(), - |artist| artist.albums.sort_unstable(), - |_| {}, - ) - } } #[cfg(test)] diff --git a/src/core/musichoard/library.rs b/src/core/musichoard/library.rs index d93c908..1ec70dc 100644 --- a/src/core/musichoard/library.rs +++ b/src/core/musichoard/library.rs @@ -11,7 +11,10 @@ use crate::core::{ database::IDatabase, library::{ILibrary, Item, Query}, }, - musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase}, + musichoard::{ + base::IMusicHoardBasePrivate, database::IMusicHoardDatabasePrivate, Error, MusicHoard, + NoDatabase, + }, }; impl MusicHoard { diff --git a/src/core/musichoard/mod.rs b/src/core/musichoard/mod.rs index 04d1cd9..2812afa 100644 --- a/src/core/musichoard/mod.rs +++ b/src/core/musichoard/mod.rs @@ -7,6 +7,7 @@ mod library; pub mod builder; pub use base::IMusicHoardBase; +pub use database::IMusicHoardDatabase; use std::{ collections::HashMap, diff --git a/src/lib.rs b/src/lib.rs index c0db04b..59f5f3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,8 @@ pub use core::collection; pub use core::interface; pub use core::musichoard::{ - builder::MusicHoardBuilder, Error, IMusicHoardBase, MusicHoard, NoDatabase, NoLibrary, + builder::MusicHoardBuilder, Error, IMusicHoardBase, IMusicHoardDatabase, MusicHoard, + NoDatabase, NoLibrary, }; #[cfg(test)] diff --git a/src/tui/lib.rs b/src/tui/lib.rs index da98a94..535be10 100644 --- a/src/tui/lib.rs +++ b/src/tui/lib.rs @@ -1,6 +1,6 @@ use musichoard::{ collection::Collection, interface::database::IDatabase, interface::library::ILibrary, - IMusicHoardBase, MusicHoard, + IMusicHoardBase, IMusicHoardDatabase, MusicHoard, }; #[cfg(test)] @@ -20,7 +20,7 @@ impl IMusicHoard for MusicHoard Result<(), musichoard::Error> { - Self::reload_database(self) + ::reload_database(self) } fn get_collection(&self) -> &Collection { diff --git a/tests/lib.rs b/tests/lib.rs index a3046f6..ddfc80f 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -9,7 +9,7 @@ mod testlib; use musichoard::{ database::json::{backend::JsonDatabaseFileBackend, JsonDatabase}, library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary}, - IMusicHoardBase, MusicHoard, + IMusicHoardBase, IMusicHoardDatabase, MusicHoard, }; use crate::testlib::COLLECTION;