Add ArtistProperties
This commit is contained in:
parent
bf5bf9d8ae
commit
6b29c97416
68
Cargo.lock
generated
68
Cargo.lock
generated
@ -184,6 +184,15 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fragile"
|
name = "fragile"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
@ -225,6 +234,16 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
@ -356,6 +375,7 @@ dependencies = [
|
|||||||
"structopt",
|
"structopt",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -436,6 +456,12 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
@ -801,6 +827,21 @@ dependencies = [
|
|||||||
"syn 2.0.11",
|
"syn 2.0.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.27.0"
|
version = "1.27.0"
|
||||||
@ -859,12 +900,27 @@ dependencies = [
|
|||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.8"
|
version = "1.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
@ -877,6 +933,18 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
@ -13,6 +13,7 @@ serde = { version = "1.0.159", features = ["derive"] }
|
|||||||
serde_json = { version = "1.0.95", optional = true}
|
serde_json = { version = "1.0.95", optional = true}
|
||||||
structopt = { version = "0.3.26", optional = true}
|
structopt = { version = "0.3.26", optional = true}
|
||||||
tokio = { version = "1.27.0", features = ["rt"], optional = true}
|
tokio = { version = "1.27.0", features = ["rt"], optional = true}
|
||||||
|
url = { version = "2.3.1", features = ["serde"] }
|
||||||
uuid = { version = "1.3.0", features = ["serde"] }
|
uuid = { version = "1.3.0", features = ["serde"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
149
src/lib.rs
149
src/lib.rs
@ -14,10 +14,133 @@ use std::{
|
|||||||
use database::IDatabase;
|
use database::IDatabase;
|
||||||
use library::{ILibrary, Item, Query};
|
use library::{ILibrary, Item, Query};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier) (MBID).
|
/// [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier) (MBID).
|
||||||
pub type Mbid = Uuid;
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
struct Mbid {
|
||||||
|
pub uuid: Uuid,
|
||||||
|
pub string: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mbid {
|
||||||
|
pub fn new<S: Into<String>>(uuid: S) -> Result<Self, Error> {
|
||||||
|
let uuid_string: String = uuid.into();
|
||||||
|
Ok(Mbid {
|
||||||
|
uuid: Uuid::try_parse(&uuid_string)?,
|
||||||
|
string: uuid_string,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
self.string.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IUrl {
|
||||||
|
fn url(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IUuid {
|
||||||
|
fn uuid(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MusicBrainz reference.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
pub struct MusicBrainz {
|
||||||
|
url: Url,
|
||||||
|
mbid: Mbid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MusicBrainz {
|
||||||
|
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||||
|
let url = Url::parse(url.as_ref())?;
|
||||||
|
let mbid: Mbid = match url.path_segments().and_then(|mut ps| ps.nth(2)) {
|
||||||
|
Some(segment) => Mbid::new(segment)?,
|
||||||
|
None => {
|
||||||
|
return Err(Error::UrlParseError(String::from(format!(
|
||||||
|
"invalid MusicBrainz URL: {}",
|
||||||
|
url.as_str()
|
||||||
|
))))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(MusicBrainz { url, mbid })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IUrl for MusicBrainz {
|
||||||
|
fn url(&self) -> &str {
|
||||||
|
self.url.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IUuid for MusicBrainz {
|
||||||
|
fn uuid(&self) -> &str {
|
||||||
|
self.mbid.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MusicButler reference.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
pub struct MusicButler {
|
||||||
|
url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MusicButler {
|
||||||
|
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||||
|
Ok(MusicButler {
|
||||||
|
url: Url::parse(url.as_ref())?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IUrl for MusicButler {
|
||||||
|
fn url(&self) -> &str {
|
||||||
|
self.url.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bandcamp reference.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
pub struct Bandcamp {
|
||||||
|
url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bandcamp {
|
||||||
|
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||||
|
Ok(Bandcamp {
|
||||||
|
url: Url::parse(url.as_ref())?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IUrl for Bandcamp {
|
||||||
|
fn url(&self) -> &str {
|
||||||
|
self.url.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Qobuz reference.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
|
pub struct Qobuz {
|
||||||
|
url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Qobuz {
|
||||||
|
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||||
|
Ok(Qobuz {
|
||||||
|
url: Url::parse(url.as_ref())?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IUrl for Qobuz {
|
||||||
|
fn url(&self) -> &str {
|
||||||
|
self.url.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The track file format.
|
/// The track file format.
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
@ -107,6 +230,15 @@ pub struct ArtistId {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The artist properties.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct ArtistProperties {
|
||||||
|
pub musicbrainz: Option<MusicBrainz>,
|
||||||
|
pub musicbutler: Vec<MusicButler>,
|
||||||
|
pub bandcamp: Vec<Bandcamp>,
|
||||||
|
pub qobuz: Option<Qobuz>,
|
||||||
|
}
|
||||||
|
|
||||||
/// An artist.
|
/// An artist.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
pub struct Artist {
|
pub struct Artist {
|
||||||
@ -194,6 +326,8 @@ pub enum Error {
|
|||||||
LibraryError(String),
|
LibraryError(String),
|
||||||
/// The [`MusicHoard`] failed to read/write from/to the database.
|
/// The [`MusicHoard`] failed to read/write from/to the database.
|
||||||
DatabaseError(String),
|
DatabaseError(String),
|
||||||
|
/// The [`MusicHoard`] failed to parse a user-provided URL.
|
||||||
|
UrlParseError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@ -203,6 +337,7 @@ impl fmt::Display for Error {
|
|||||||
Self::DatabaseError(ref s) => {
|
Self::DatabaseError(ref s) => {
|
||||||
write!(f, "failed to read/write from/to the database: {s}")
|
write!(f, "failed to read/write from/to the database: {s}")
|
||||||
}
|
}
|
||||||
|
Self::UrlParseError(ref s) => write!(f, "failed to parse a user-provided URL: {s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,6 +360,18 @@ impl From<database::SaveError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<url::ParseError> for Error {
|
||||||
|
fn from(err: url::ParseError) -> Error {
|
||||||
|
Error::UrlParseError(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<uuid::Error> for Error {
|
||||||
|
fn from(err: uuid::Error) -> Error {
|
||||||
|
Error::UrlParseError(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The Music Hoard. It is responsible for pulling information from both the library and the
|
/// The Music Hoard. It is responsible for pulling information from both the library and the
|
||||||
/// database, ensuring its consistent and writing back any changes.
|
/// database, ensuring its consistent and writing back any changes.
|
||||||
pub struct MusicHoard<LIB, DB> {
|
pub struct MusicHoard<LIB, DB> {
|
||||||
|
Loading…
Reference in New Issue
Block a user