Add ArtistProperties
This commit is contained in:
parent
bf5bf9d8ae
commit
e3817b3c28
68
Cargo.lock
generated
68
Cargo.lock
generated
@ -184,6 +184,15 @@ dependencies = [
|
||||
"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]]
|
||||
name = "fragile"
|
||||
version = "2.0.0"
|
||||
@ -225,6 +234,16 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
@ -356,6 +375,7 @@ dependencies = [
|
||||
"structopt",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@ -436,6 +456,12 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
@ -801,6 +827,21 @@ dependencies = [
|
||||
"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]]
|
||||
name = "tokio"
|
||||
version = "1.27.0"
|
||||
@ -859,12 +900,27 @@ dependencies = [
|
||||
"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]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
@ -877,6 +933,18 @@ version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "uuid"
|
||||
version = "1.3.0"
|
||||
|
@ -13,6 +13,7 @@ serde = { version = "1.0.159", features = ["derive"] }
|
||||
serde_json = { version = "1.0.95", optional = true}
|
||||
structopt = { version = "0.3.26", 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"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
144
src/lib.rs
144
src/lib.rs
@ -14,10 +14,128 @@ use std::{
|
||||
use database::IDatabase;
|
||||
use library::{ILibrary, Item, Query};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// [MusicBrainz Identifier](https://musicbrainz.org/doc/MusicBrainz_Identifier) (MBID).
|
||||
pub type Mbid = Uuid;
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct Mbid {
|
||||
string: String,
|
||||
uuid: Uuid,
|
||||
}
|
||||
|
||||
impl Mbid {
|
||||
pub fn new<S: Into<String>>(uuid: S) -> Result<Self, Error> {
|
||||
let string: String = uuid.into();
|
||||
let uuid = Uuid::try_parse(&string)?;
|
||||
Ok(Mbid { string, uuid })
|
||||
}
|
||||
|
||||
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> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
Ok(MusicButler { url })
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
Ok(Bandcamp { url })
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
Ok(Qobuz { url })
|
||||
}
|
||||
}
|
||||
|
||||
impl IUrl for Qobuz {
|
||||
fn url(&self) -> &str {
|
||||
self.url.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
/// The track file format.
|
||||
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
@ -107,6 +225,15 @@ pub struct ArtistId {
|
||||
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.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||
pub struct Artist {
|
||||
@ -194,6 +321,8 @@ pub enum Error {
|
||||
LibraryError(String),
|
||||
/// The [`MusicHoard`] failed to read/write from/to the database.
|
||||
DatabaseError(String),
|
||||
/// The [`MusicHoard`] failed to parse a user-provided URL.
|
||||
UrlParseError(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@ -203,6 +332,7 @@ impl fmt::Display for Error {
|
||||
Self::DatabaseError(ref 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 +355,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
|
||||
/// database, ensuring its consistent and writing back any changes.
|
||||
pub struct MusicHoard<LIB, DB> {
|
||||
|
Loading…
Reference in New Issue
Block a user