Create the main binary
This commit is contained in:
parent
16045a6c85
commit
5250b1b93a
184
Cargo.lock
generated
184
Cargo.lock
generated
@ -2,6 +2,26 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@ -20,6 +40,21 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.0"
|
||||
@ -50,6 +85,24 @@ dependencies = [
|
||||
"instant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.1"
|
||||
@ -71,7 +124,7 @@ version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
@ -82,6 +135,12 @@ version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
@ -101,6 +160,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"structopt",
|
||||
"tempfile",
|
||||
"uuid",
|
||||
]
|
||||
@ -111,6 +171,30 @@ version = "1.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.54"
|
||||
@ -175,7 +259,7 @@ checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -189,6 +273,47 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "structopt"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"lazy_static",
|
||||
"structopt-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structopt-derive"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.11"
|
||||
@ -213,12 +338,33 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.3.0"
|
||||
@ -228,6 +374,40 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
structopt = "0.3"
|
||||
uuid = { version = "1.3", features = ["serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -4,7 +4,9 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt::Display,
|
||||
process::Command, path::{PathBuf, Path},
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
str,
|
||||
};
|
||||
|
||||
use crate::{Album, AlbumId, Artist, ArtistId, Track};
|
||||
@ -228,17 +230,22 @@ pub struct SystemExecutor {
|
||||
}
|
||||
|
||||
impl SystemExecutor {
|
||||
pub fn new(bin: &str, path: Option<&Path>) -> SystemExecutor {
|
||||
pub fn new(bin: &str) -> Self {
|
||||
SystemExecutor {
|
||||
bin: bin.to_string(),
|
||||
config: path.map(|p| p.to_path_buf()),
|
||||
config: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config(mut self, path: Option<&Path>) -> Self {
|
||||
self.config = path.map(|p| p.to_path_buf());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SystemExecutor {
|
||||
fn default() -> Self {
|
||||
SystemExecutor::new("beet", None)
|
||||
SystemExecutor::new("beet")
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,7 +257,12 @@ impl BeetsExecutor for SystemExecutor {
|
||||
cmd.arg(path);
|
||||
}
|
||||
let output = cmd.args(arguments).output()?;
|
||||
let output = std::str::from_utf8(&output.stdout)?;
|
||||
if !output.status.success() {
|
||||
return Err(Error::CmdExecError(
|
||||
String::from_utf8_lossy(&output.stderr).to_string(),
|
||||
));
|
||||
}
|
||||
let output = str::from_utf8(&output.stdout)?;
|
||||
Ok(output.split('\n').map(|s| s.to_string()).collect())
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Module for interacting with the music library.
|
||||
|
||||
use std::{num::ParseIntError, str::Utf8Error};
|
||||
use std::{num::ParseIntError, str::Utf8Error, fmt};
|
||||
|
||||
use crate::Artist;
|
||||
|
||||
@ -98,6 +98,8 @@ impl Query {
|
||||
/// Error type for library calls.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// The underlying library failed to execute a command.
|
||||
CmdExecError(String),
|
||||
/// The underlying library returned invalid data.
|
||||
InvalidData(String),
|
||||
/// The underlying library experienced an I/O error.
|
||||
@ -126,6 +128,12 @@ impl From<Utf8Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:#?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for interacting with the music library.
|
||||
pub trait Library {
|
||||
/// List lirbary items that match the a specific query.
|
||||
|
57
src/main.rs
Normal file
57
src/main.rs
Normal file
@ -0,0 +1,57 @@
|
||||
use std::{path::PathBuf, process::exit};
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
use musichoard::{
|
||||
database::{
|
||||
json::{DatabaseJson, DatabaseJsonFile},
|
||||
DatabaseWrite,
|
||||
},
|
||||
library::{
|
||||
beets::{Beets, SystemExecutor},
|
||||
Library, Query,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(StructOpt)]
|
||||
struct Opt {
|
||||
#[structopt(
|
||||
short = "b",
|
||||
long = "beets-config",
|
||||
name = "beets config file path",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
beets_config_file_path: Option<PathBuf>,
|
||||
|
||||
#[structopt(
|
||||
short = "d",
|
||||
long = "database",
|
||||
name = "database file path",
|
||||
default_value = "database.json",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
database_file_path: PathBuf,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let opt = Opt::from_args();
|
||||
|
||||
let mut beets = Beets::new(Box::new(
|
||||
SystemExecutor::default().config(opt.beets_config_file_path.as_deref()),
|
||||
));
|
||||
|
||||
let collection = match beets.list(&Query::new()) {
|
||||
Ok(collection) => collection,
|
||||
Err(e) => {
|
||||
println!("{e}");
|
||||
exit(1)
|
||||
}
|
||||
};
|
||||
|
||||
let mut database = DatabaseJson::new(Box::new(DatabaseJsonFile::new(&opt.database_file_path)));
|
||||
|
||||
if let Err(e) = database.write(&collection) {
|
||||
println!("{e}");
|
||||
exit(1)
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ use crate::COLLECTION;
|
||||
|
||||
#[test]
|
||||
fn test_no_config_list() {
|
||||
let executor = SystemExecutor::new("beet", None);
|
||||
let executor = SystemExecutor::default();
|
||||
|
||||
let mut beets = Beets::new(Box::new(executor));
|
||||
let output = beets.list(&Query::default()).unwrap();
|
||||
@ -23,10 +23,9 @@ fn test_no_config_list() {
|
||||
|
||||
#[test]
|
||||
fn test_full_list() {
|
||||
let executor = SystemExecutor::new(
|
||||
"beet",
|
||||
Some(&fs::canonicalize("./tests/files/library/config.yml").unwrap()),
|
||||
);
|
||||
let executor = SystemExecutor::default().config(Some(
|
||||
&fs::canonicalize("./tests/files/library/config.yml").unwrap(),
|
||||
));
|
||||
|
||||
let mut beets = Beets::new(Box::new(executor));
|
||||
let output = beets.list(&Query::default()).unwrap();
|
||||
@ -37,10 +36,9 @@ fn test_full_list() {
|
||||
|
||||
#[test]
|
||||
fn test_album_artist_query() {
|
||||
let executor = SystemExecutor::new(
|
||||
"beet",
|
||||
Some(&fs::canonicalize("./tests/files/library/config.yml").unwrap()),
|
||||
);
|
||||
let executor = SystemExecutor::default().config(Some(
|
||||
&fs::canonicalize("./tests/files/library/config.yml").unwrap(),
|
||||
));
|
||||
|
||||
let mut beets = Beets::new(Box::new(executor));
|
||||
let output = beets
|
||||
@ -53,27 +51,24 @@ fn test_album_artist_query() {
|
||||
|
||||
#[test]
|
||||
fn test_album_title_query() {
|
||||
let executor = SystemExecutor::new(
|
||||
"beet",
|
||||
Some(&fs::canonicalize("./tests/files/library/config.yml").unwrap()),
|
||||
);
|
||||
let executor = SystemExecutor::default().config(Some(
|
||||
&fs::canonicalize("./tests/files/library/config.yml").unwrap(),
|
||||
));
|
||||
|
||||
let mut beets = Beets::new(Box::new(executor));
|
||||
let output = beets
|
||||
.list(&Query::default().album_title(QueryOption::Include(String::from("Slovo"))))
|
||||
.unwrap();
|
||||
|
||||
|
||||
let expected: Vec<Artist> = COLLECTION[0..1].to_owned();
|
||||
assert_eq!(output, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exclude_query() {
|
||||
let executor = SystemExecutor::new(
|
||||
"beet",
|
||||
Some(&fs::canonicalize("./tests/files/library/config.yml").unwrap()),
|
||||
);
|
||||
let executor = SystemExecutor::default().config(Some(
|
||||
&fs::canonicalize("./tests/files/library/config.yml").unwrap(),
|
||||
));
|
||||
|
||||
let mut beets = Beets::new(Box::new(executor));
|
||||
let output = beets
|
||||
|
Loading…
Reference in New Issue
Block a user