Break down the musichoard files #165
@ -5,7 +5,7 @@ use structopt::{clap::AppSettings, StructOpt};
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
collection::{album::AlbumId, artist::ArtistId},
|
collection::{album::AlbumId, artist::ArtistId},
|
||||||
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
||||||
MusicHoard, MusicHoardBuilder, NoLibrary,
|
IMusicHoardDatabase, MusicHoard, MusicHoardBuilder, NoLibrary,
|
||||||
};
|
};
|
||||||
|
|
||||||
type MH = MusicHoard<JsonDatabase<JsonDatabaseFileBackend>, NoLibrary>;
|
type MH = MusicHoard<JsonDatabase<JsonDatabaseFileBackend>, NoLibrary>;
|
||||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use crate::{
|
use crate::{
|
||||||
core::{
|
core::{
|
||||||
interface::{database::IDatabase, library::ILibrary},
|
interface::{database::IDatabase, library::ILibrary},
|
||||||
musichoard::{MusicHoard, NoDatabase, NoLibrary},
|
musichoard::{database::IMusicHoardDatabase, MusicHoard, NoDatabase, NoLibrary},
|
||||||
},
|
},
|
||||||
Error,
|
Error,
|
||||||
};
|
};
|
||||||
|
@ -9,16 +9,66 @@ use crate::core::{
|
|||||||
musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase},
|
musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<Library> MusicHoard<NoDatabase, Library> {
|
pub trait IMusicHoardDatabase {
|
||||||
pub fn commit(&mut self) -> Result<(), Error> {
|
fn reload_database(&mut self) -> Result<(), Error>;
|
||||||
self.collection = self.pre_commit.clone();
|
|
||||||
Ok(())
|
fn add_artist<IntoId: Into<ArtistId>>(&mut self, artist_id: IntoId) -> Result<(), Error>;
|
||||||
}
|
fn remove_artist<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
|
||||||
|
|
||||||
|
fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
artist_sort: IntoId,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn clear_artist_sort<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
|
||||||
|
|
||||||
|
fn set_artist_musicbrainz<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
url: S,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn clear_artist_musicbrainz<Id: AsRef<ArtistId>>(&mut self, artist_id: Id)
|
||||||
|
-> Result<(), Error>;
|
||||||
|
|
||||||
|
fn add_to_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn remove_from_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn set_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn clear_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
|
||||||
|
fn set_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: ArtistIdRef,
|
||||||
|
album_id: AlbumIdRef,
|
||||||
|
seq: u8,
|
||||||
|
) -> Result<(), Error>;
|
||||||
|
fn clear_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: ArtistIdRef,
|
||||||
|
album_id: AlbumIdRef,
|
||||||
|
) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Database: IDatabase, Library> MusicHoard<Database, Library> {
|
impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database, Library> {
|
||||||
/// Load the database and merge with the in-memory collection.
|
fn reload_database(&mut self) -> Result<(), Error> {
|
||||||
pub fn reload_database(&mut self) -> Result<(), Error> {
|
|
||||||
self.database_cache = self.database.load()?;
|
self.database_cache = self.database.load()?;
|
||||||
Self::sort_albums_and_tracks(self.database_cache.iter_mut());
|
Self::sort_albums_and_tracks(self.database_cache.iter_mut());
|
||||||
|
|
||||||
@ -28,7 +78,146 @@ impl<Database: IDatabase, Library> MusicHoard<Database, Library> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&mut self) -> Result<(), Error> {
|
fn add_artist<IntoId: Into<ArtistId>>(&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<Id: AsRef<ArtistId>>(&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<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
||||||
|
&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<Id: AsRef<ArtistId>>(&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<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&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<Id: AsRef<ArtistId>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.update_artist(artist_id.as_ref(), |artist| artist.clear_musicbrainz_url())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_to_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.update_artist(artist_id.as_ref(), |artist| {
|
||||||
|
artist.add_to_property(property, values)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove_from_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.update_artist(artist_id.as_ref(), |artist| {
|
||||||
|
artist.remove_from_property(property, values)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||||
|
&mut self,
|
||||||
|
artist_id: Id,
|
||||||
|
property: S,
|
||||||
|
values: Vec<S>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.update_artist(artist_id.as_ref(), |artist| {
|
||||||
|
artist.set_property(property, values)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||||
|
&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<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||||
|
&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<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||||
|
&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<Library> IMusicHoardDatabasePrivate for MusicHoard<NoDatabase, Library> {
|
||||||
|
fn commit(&mut self) -> Result<(), Error> {
|
||||||
|
self.collection = self.pre_commit.clone();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Database: IDatabase, Library> IMusicHoardDatabasePrivate for MusicHoard<Database, Library> {
|
||||||
|
fn commit(&mut self) -> Result<(), Error> {
|
||||||
if self.collection != self.pre_commit {
|
if self.collection != self.pre_commit {
|
||||||
if let Err(err) = self.database.save(&self.pre_commit) {
|
if let Err(err) = self.database.save(&self.pre_commit) {
|
||||||
self.pre_commit = self.collection.clone();
|
self.pre_commit = self.collection.clone();
|
||||||
@ -38,7 +227,9 @@ impl<Database: IDatabase, Library> MusicHoard<Database, Library> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Database: IDatabase, Library> MusicHoard<Database, Library> {
|
||||||
fn update_collection<FnColl>(&mut self, fn_coll: FnColl) -> Result<(), Error>
|
fn update_collection<FnColl>(&mut self, fn_coll: FnColl) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
FnColl: FnOnce(&mut Collection),
|
FnColl: FnOnce(&mut Collection),
|
||||||
@ -92,132 +283,6 @@ impl<Database: IDatabase, Library> MusicHoard<Database, Library> {
|
|||||||
fn_artist(artist);
|
fn_artist(artist);
|
||||||
self.update_collection(fn_coll)
|
self.update_collection(fn_coll)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_artist<IntoId: Into<ArtistId>>(&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<Id: AsRef<ArtistId>>(&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<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
|
||||||
&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<Id: AsRef<ArtistId>>(&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<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
|
||||||
&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<Id: AsRef<ArtistId>>(
|
|
||||||
&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<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
|
||||||
&mut self,
|
|
||||||
artist_id: Id,
|
|
||||||
property: S,
|
|
||||||
values: Vec<S>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.update_artist(artist_id.as_ref(), |artist| {
|
|
||||||
artist.add_to_property(property, values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_from_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
|
||||||
&mut self,
|
|
||||||
artist_id: Id,
|
|
||||||
property: S,
|
|
||||||
values: Vec<S>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.update_artist(artist_id.as_ref(), |artist| {
|
|
||||||
artist.remove_from_property(property, values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
|
||||||
&mut self,
|
|
||||||
artist_id: Id,
|
|
||||||
property: S,
|
|
||||||
values: Vec<S>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
self.update_artist(artist_id.as_ref(), |artist| {
|
|
||||||
artist.set_property(property, values)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
|
||||||
&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<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
|
||||||
&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<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
|
||||||
&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)]
|
#[cfg(test)]
|
||||||
|
@ -11,7 +11,10 @@ use crate::core::{
|
|||||||
database::IDatabase,
|
database::IDatabase,
|
||||||
library::{ILibrary, Item, Query},
|
library::{ILibrary, Item, Query},
|
||||||
},
|
},
|
||||||
musichoard::{base::IMusicHoardBasePrivate, Error, MusicHoard, NoDatabase},
|
musichoard::{
|
||||||
|
base::IMusicHoardBasePrivate, database::IMusicHoardDatabasePrivate, Error, MusicHoard,
|
||||||
|
NoDatabase,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<Library: ILibrary> MusicHoard<NoDatabase, Library> {
|
impl<Library: ILibrary> MusicHoard<NoDatabase, Library> {
|
||||||
|
@ -7,6 +7,7 @@ mod library;
|
|||||||
pub mod builder;
|
pub mod builder;
|
||||||
|
|
||||||
pub use base::IMusicHoardBase;
|
pub use base::IMusicHoardBase;
|
||||||
|
pub use database::IMusicHoardDatabase;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
@ -8,7 +8,8 @@ pub use core::collection;
|
|||||||
pub use core::interface;
|
pub use core::interface;
|
||||||
|
|
||||||
pub use core::musichoard::{
|
pub use core::musichoard::{
|
||||||
builder::MusicHoardBuilder, Error, IMusicHoardBase, MusicHoard, NoDatabase, NoLibrary,
|
builder::MusicHoardBuilder, Error, IMusicHoardBase, IMusicHoardDatabase, MusicHoard,
|
||||||
|
NoDatabase, NoLibrary,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
collection::Collection, interface::database::IDatabase, interface::library::ILibrary,
|
collection::Collection, interface::database::IDatabase, interface::library::ILibrary,
|
||||||
IMusicHoardBase, MusicHoard,
|
IMusicHoardBase, IMusicHoardDatabase, MusicHoard,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -20,7 +20,7 @@ impl<Database: IDatabase, Library: ILibrary> IMusicHoard for MusicHoard<Database
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reload_database(&mut self) -> Result<(), musichoard::Error> {
|
fn reload_database(&mut self) -> Result<(), musichoard::Error> {
|
||||||
Self::reload_database(self)
|
<Self as IMusicHoardDatabase>::reload_database(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_collection(&self) -> &Collection {
|
fn get_collection(&self) -> &Collection {
|
||||||
|
@ -9,7 +9,7 @@ mod testlib;
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
database::json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
||||||
library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
||||||
IMusicHoardBase, MusicHoard,
|
IMusicHoardBase, IMusicHoardDatabase, MusicHoard,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::testlib::COLLECTION;
|
use crate::testlib::COLLECTION;
|
||||||
|
Loading…
Reference in New Issue
Block a user