From 175d304f1b8674e1a7bf6073f977c63a334f21b6 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sat, 30 Jul 2022 00:06:21 -0400 Subject: [PATCH] cargo fmt --- interpreter/benches/file_parse.rs | 5 +- interpreter/src/context.rs | 2 +- interpreter/src/debug.rs | 20 +- interpreter/src/faye.rs | 18 +- interpreter/src/lang/filter.rs | 29 +-- interpreter/src/lang/filter_replace.rs | 5 +- interpreter/src/lang/iter_block.rs | 15 +- interpreter/src/lang/mod.rs | 4 +- interpreter/src/lang/utility.rs | 7 +- interpreter/src/lang/vocabulary/empties.rs | 2 +- .../lang/vocabulary/filters/field_filter.rs | 6 +- .../vocabulary/filters/field_like_filter.rs | 16 +- .../vocabulary/filters/field_match_filter.rs | 6 +- .../vocabulary/filters/nonempty_filter.rs | 5 +- .../src/lang/vocabulary/filters/unique.rs | 3 +- .../src/lang/vocabulary/item_ops/add.rs | 4 +- .../lang/vocabulary/item_ops/field_assign.rs | 2 +- .../src/lang/vocabulary/item_ops/negate.rs | 4 +- .../src/lang/vocabulary/item_ops/not.rs | 4 +- .../src/lang/vocabulary/item_ops/subtract.rs | 4 +- interpreter/src/lang/vocabulary/mpd_query.rs | 102 +++++--- interpreter/src/lang/vocabulary/repeat.rs | 7 +- .../vocabulary/sorters/bliss_next_sorter.rs | 2 +- .../lang/vocabulary/sorters/bliss_sorter.rs | 2 +- .../lang/vocabulary/sorters/empty_sorter.rs | 2 +- .../lang/vocabulary/sorters/field_sorter.rs | 2 +- .../src/lang/vocabulary/sorters/shuffle.rs | 5 +- interpreter/src/lang/vocabulary/sql_query.rs | 3 +- .../src/lang/vocabulary/sql_simple_query.rs | 3 +- .../src/lang/vocabulary/variable_assign.rs | 16 +- interpreter/src/music/build_library.rs | 5 +- interpreter/src/music/library.rs | 2 +- interpreter/src/music/tag.rs | 4 +- interpreter/src/processing/filesystem.rs | 7 +- interpreter/src/processing/mod.rs | 8 +- interpreter/src/processing/mpd.rs | 39 ++- interpreter/src/processing/music_analysis.rs | 180 ++++++++------ interpreter/src/processing/sql.rs | 2 +- interpreter/src/processing/variables.rs | 2 +- interpreter/src/tokens/tokenizer.rs | 2 +- interpreter/tests/single_line.rs | 38 +-- m3u8/src/main.rs | 10 +- player/src/controller.rs | 33 +-- player/src/errors.rs | 6 +- player/src/lib.rs | 4 +- player/src/os_controls.rs | 4 +- player/src/player.rs | 29 ++- player/src/player_wrapper.rs | 6 +- player/src/uri.rs | 10 +- src/cli.rs | 4 +- src/main.rs | 7 +- src/repl.rs | 222 +++++++++++------- 52 files changed, 495 insertions(+), 434 deletions(-) diff --git a/interpreter/benches/file_parse.rs b/interpreter/benches/file_parse.rs index 8c7603f..1d5495c 100644 --- a/interpreter/benches/file_parse.rs +++ b/interpreter/benches/file_parse.rs @@ -51,5 +51,8 @@ fn faye_benchmark(c: &mut Criterion) { }); } -criterion_group!(parse_benches, /*interpretor_benchmark,*/ faye_benchmark); +criterion_group!( + parse_benches, + /*interpretor_benchmark,*/ faye_benchmark +); criterion_main!(parse_benches); diff --git a/interpreter/src/context.rs b/interpreter/src/context.rs index b1d89b3..3e54fe4 100644 --- a/interpreter/src/context.rs +++ b/interpreter/src/context.rs @@ -2,7 +2,7 @@ use super::processing::advanced::{DefaultAnalyzer, MusicAnalyzer}; use super::processing::database::{DatabaseQuerier, SQLiteExecutor}; #[cfg(feature = "mpd")] -use super::processing::database::{MpdQuerier, MpdExecutor}; +use super::processing::database::{MpdExecutor, MpdQuerier}; use super::processing::general::{ FilesystemExecutor, FilesystemQuerier, OpStorage, VariableStorer, }; diff --git a/interpreter/src/debug.rs b/interpreter/src/debug.rs index 4f76d3e..7bd15b7 100644 --- a/interpreter/src/debug.rs +++ b/interpreter/src/debug.rs @@ -7,10 +7,7 @@ use super::{Interpreter, InterpreterItem}; pub struct Debugger<'a, T, F> where T: TokenReader, - F: Fn( - &mut Interpreter<'a, T>, - Option, - ) -> Option, + F: Fn(&mut Interpreter<'a, T>, Option) -> Option, { interpreter: Interpreter<'a, T>, transmuter: F, @@ -19,16 +16,10 @@ where impl<'a, T, F> Debugger<'a, T, F> where T: TokenReader, - F: Fn( - &mut Interpreter<'a, T>, - Option, - ) -> Option, + F: Fn(&mut Interpreter<'a, T>, Option) -> Option, { /// Create a new instance of Debugger using the provided interpreter and callback. - pub fn new( - faye: Interpreter<'a, T>, - item_handler: F, - ) -> Self { + pub fn new(faye: Interpreter<'a, T>, item_handler: F) -> Self { Self { interpreter: faye, transmuter: item_handler, @@ -39,10 +30,7 @@ where impl<'a, T, F> Iterator for Debugger<'a, T, F> where T: TokenReader, - F: Fn( - &mut Interpreter<'a, T>, - Option, - ) -> Option, + F: Fn(&mut Interpreter<'a, T>, Option) -> Option, { type Item = InterpreterItem; diff --git a/interpreter/src/faye.rs b/interpreter/src/faye.rs index 66ef982..e632bf4 100644 --- a/interpreter/src/faye.rs +++ b/interpreter/src/faye.rs @@ -61,7 +61,13 @@ impl<'a, R: Read> Interpreter<'a, Tokenizer> { Self::with_standard_vocab(tokenizer) } - pub fn with_stream_and_callback(stream: R, callback: &'a dyn Fn(&mut Interpreter<'a, Tokenizer>, InterpreterEvent) -> Result<(), InterpreterError>) -> Self { + pub fn with_stream_and_callback( + stream: R, + callback: &'a dyn Fn( + &mut Interpreter<'a, Tokenizer>, + InterpreterEvent, + ) -> Result<(), InterpreterError>, + ) -> Self { let tokenizer = Tokenizer::new(stream); let vocab = LanguageDictionary::standard(); Self::with(vocab, tokenizer, callback) @@ -89,7 +95,10 @@ where pub fn with( vocab: LanguageDictionary, token_reader: T, - callback: &'a dyn Fn(&mut Interpreter<'a, T>, InterpreterEvent) -> Result<(), InterpreterError>, + callback: &'a dyn Fn( + &mut Interpreter<'a, T>, + InterpreterEvent, + ) -> Result<(), InterpreterError>, ) -> Self { Self { tokenizer: token_reader, @@ -190,7 +199,10 @@ where } } -fn error_with_ctx>(error: T, line: usize) -> InterpreterError { +fn error_with_ctx>( + error: T, + line: usize, +) -> InterpreterError { let mut err = error.into(); err.set_line(line); err diff --git a/interpreter/src/lang/filter.rs b/interpreter/src/lang/filter.rs index 90bcec6..371bed8 100644 --- a/interpreter/src/lang/filter.rs +++ b/interpreter/src/lang/filter.rs @@ -237,15 +237,14 @@ impl Iterator for FilterStatement

{ // handle other filters // make fake inner item let single_op = SingleItem::new_ok(item.clone()); - match ctx.variables.declare( - INNER_VARIABLE_NAME, - Type::Op(Box::new(single_op)), - ) { + match ctx + .variables + .declare(INNER_VARIABLE_NAME, Type::Op(Box::new(single_op))) + { Ok(x) => x, Err(e) => { //self.context = Some(op.escape()); - maybe_result = - Some(Err(e.with(RuntimeOp(fake)))); + maybe_result = Some(Err(e.with(RuntimeOp(fake)))); self.context = Some(ctx); break; } @@ -268,9 +267,8 @@ impl Iterator for FilterStatement

{ Ok(_) => {} Err(e) => match maybe_result { Some(Ok(_)) => { - maybe_result = Some(Err( - e.with(RuntimeOp(fake)) - )) + maybe_result = + Some(Err(e.with(RuntimeOp(fake)))) } Some(Err(e2)) => maybe_result = Some(Err(e2)), // already failing, do not replace error, None => {} // impossible @@ -332,8 +330,8 @@ impl Iterator for FilterStatement

{ } Err(e) => { self.is_failing = true; // this is unrecoverable and reproducible, so it shouldn't be tried again (to prevent error spam) - return Some(Err(e.with(RuntimeOp(fake)))) - }, + return Some(Err(e.with(RuntimeOp(fake)))); + } }; let mut maybe_result = None; let ctx = self.context.take().unwrap(); @@ -457,17 +455,12 @@ impl Iterator for FilterStatement

{ } } -pub struct FilterStatementFactory< - P: FilterPredicate + 'static, - F: FilterFactory

+ 'static, -> { +pub struct FilterStatementFactory + 'static> { filter_factory: F, idc: PhantomData

, } -impl + 'static> - FilterStatementFactory -{ +impl + 'static> FilterStatementFactory { pub fn new(factory: F) -> Self { Self { filter_factory: factory, diff --git a/interpreter/src/lang/filter_replace.rs b/interpreter/src/lang/filter_replace.rs index cc24aee..59b41e0 100644 --- a/interpreter/src/lang/filter_replace.rs +++ b/interpreter/src/lang/filter_replace.rs @@ -354,10 +354,7 @@ fn declare_or_replace_item( Ok(old_item) } -fn remove_or_replace_item( - old_item: Option, - ctx: &mut Context, -) -> Result<(), RuntimeMsg> { +fn remove_or_replace_item(old_item: Option, ctx: &mut Context) -> Result<(), RuntimeMsg> { ctx.variables.remove(ITEM_VARIABLE_NAME)?; if let Some(old_item) = old_item { ctx.variables.declare(ITEM_VARIABLE_NAME, old_item)?; diff --git a/interpreter/src/lang/iter_block.rs b/interpreter/src/lang/iter_block.rs index 6d476e2..6adf2be 100644 --- a/interpreter/src/lang/iter_block.rs +++ b/interpreter/src/lang/iter_block.rs @@ -189,10 +189,7 @@ impl Iterator for ItemBlockStatement { return Some(Err(RuntimeError { line: 0, op: PseudoOp::from_printable(self), - msg: format!( - "Expected `item` like Type::Item(Item[...]), got {}", - x - ), + msg: format!("Expected `item` like Type::Item(Item[...]), got {}", x), })) } None => {} @@ -214,10 +211,7 @@ pub struct ItemBlockFactory { } impl ItemBlockFactory { - pub fn push< - T: ItemOpFactory + 'static, - Y: Deref + ItemOp + 'static, - >( + pub fn push + 'static, Y: Deref + ItemOp + 'static>( mut self, factory: T, ) -> Self { @@ -314,10 +308,7 @@ fn replace_item_var(ctx: &mut Context, item: Type) -> Option { old_var } -fn restore_item_var( - ctx: &mut Context, - old_var: Option, -) -> Result, RuntimeMsg> { +fn restore_item_var(ctx: &mut Context, old_var: Option) -> Result, RuntimeMsg> { let new_var = if ctx.variables.exists(ITEM_VARIABLE_NAME) { Some(ctx.variables.remove(ITEM_VARIABLE_NAME)?) } else { diff --git a/interpreter/src/lang/mod.rs b/interpreter/src/lang/mod.rs index 2cd4ee8..05b1714 100644 --- a/interpreter/src/lang/mod.rs +++ b/interpreter/src/lang/mod.rs @@ -20,9 +20,7 @@ pub(crate) mod utility; pub use dictionary::LanguageDictionary; pub(crate) use error::LanguageError; pub use error::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; -pub use filter::{ - FilterFactory, FilterPredicate, FilterStatement, FilterStatementFactory, -}; +pub use filter::{FilterFactory, FilterPredicate, FilterStatement, FilterStatementFactory}; pub use filter_replace::FilterReplaceStatement; pub use function::{FunctionFactory, FunctionStatementFactory}; pub use iter_block::{ItemBlockFactory, ItemOp, ItemOpFactory}; diff --git a/interpreter/src/lang/utility.rs b/interpreter/src/lang/utility.rs index 99b4d92..c25e448 100644 --- a/interpreter/src/lang/utility.rs +++ b/interpreter/src/lang/utility.rs @@ -1,8 +1,8 @@ use std::collections::VecDeque; use std::path::PathBuf; -use super::TypePrimitive; use super::SyntaxError; +use super::TypePrimitive; use crate::tokens::Token; pub fn assert_token Option>( @@ -29,10 +29,7 @@ pub fn assert_token Option>( } } -pub fn assert_token_raw( - token: Token, - tokens: &mut VecDeque, -) -> Result { +pub fn assert_token_raw(token: Token, tokens: &mut VecDeque) -> Result { let result = match tokens.pop_front() { Some(x) => Ok(x), None => Err(SyntaxError { diff --git a/interpreter/src/lang/vocabulary/empties.rs b/interpreter/src/lang/vocabulary/empties.rs index ba5bc49..67d234a 100644 --- a/interpreter/src/lang/vocabulary/empties.rs +++ b/interpreter/src/lang/vocabulary/empties.rs @@ -5,8 +5,8 @@ use std::iter::Iterator; use crate::tokens::Token; use crate::Context; -use crate::lang::{Lookup, LanguageDictionary, PseudoOp}; use crate::lang::{FunctionFactory, FunctionStatementFactory, IteratorItem, Op}; +use crate::lang::{LanguageDictionary, Lookup, PseudoOp}; use crate::lang::{RuntimeError, RuntimeOp, SyntaxError}; use crate::processing::general::Type; use crate::Item; diff --git a/interpreter/src/lang/vocabulary/filters/field_filter.rs b/interpreter/src/lang/vocabulary/filters/field_filter.rs index 63598b1..fdb812f 100644 --- a/interpreter/src/lang/vocabulary/filters/field_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/field_filter.rs @@ -47,11 +47,7 @@ impl Display for FieldFilter { } impl FilterPredicate for FieldFilter { - fn matches( - &mut self, - music_item_lut: &Item, - ctx: &mut Context, - ) -> Result { + fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result { let variable = match &self.val { VariableOrValue::Variable(name) => match ctx.variables.get(name)? { Type::Primitive(t) => Ok(t), diff --git a/interpreter/src/lang/vocabulary/filters/field_like_filter.rs b/interpreter/src/lang/vocabulary/filters/field_like_filter.rs index 8bca400..3032cad 100644 --- a/interpreter/src/lang/vocabulary/filters/field_like_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/field_like_filter.rs @@ -40,11 +40,7 @@ impl Display for FieldLikeFilter { } impl FilterPredicate for FieldLikeFilter { - fn matches( - &mut self, - music_item_lut: &Item, - ctx: &mut Context, - ) -> Result { + fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result { let variable = match &self.val { VariableOrValue::Variable(name) => match ctx.variables.get(name)? { Type::Primitive(TypePrimitive::String(s)) => Ok(s), @@ -122,13 +118,11 @@ impl FilterFactory for FieldLikeFilterFactory { }; let name = assert_token( |t| match t { - Token::Name(s) => { - match &s as _ { - "unlike" | "like" => Some(s), - _ => None, - } + Token::Name(s) => match &s as _ { + "unlike" | "like" => Some(s), + _ => None, }, - _ => None + _ => None, }, Token::Literal("like|unlike".into()), tokens, diff --git a/interpreter/src/lang/vocabulary/filters/field_match_filter.rs b/interpreter/src/lang/vocabulary/filters/field_match_filter.rs index e4b4cba..853e571 100644 --- a/interpreter/src/lang/vocabulary/filters/field_match_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/field_match_filter.rs @@ -33,11 +33,7 @@ impl Display for FieldRegexFilter { } impl FilterPredicate for FieldRegexFilter { - fn matches( - &mut self, - music_item_lut: &Item, - ctx: &mut Context, - ) -> Result { + fn matches(&mut self, music_item_lut: &Item, ctx: &mut Context) -> Result { let variable = match &self.val { VariableOrValue::Variable(name) => match ctx.variables.get(name)? { Type::Primitive(TypePrimitive::String(s)) => Ok(s), diff --git a/interpreter/src/lang/vocabulary/filters/nonempty_filter.rs b/interpreter/src/lang/vocabulary/filters/nonempty_filter.rs index e7278e6..67402fa 100644 --- a/interpreter/src/lang/vocabulary/filters/nonempty_filter.rs +++ b/interpreter/src/lang/vocabulary/filters/nonempty_filter.rs @@ -2,8 +2,8 @@ use std::collections::VecDeque; use std::fmt::{Debug, Display, Error, Formatter}; use crate::lang::LanguageDictionary; +use crate::lang::{utility::assert_token_raw, RuntimeMsg, SyntaxError}; use crate::lang::{FilterFactory, FilterPredicate, FilterStatementFactory}; -use crate::lang::{RuntimeMsg, SyntaxError, utility::assert_token_raw}; use crate::tokens::Token; use crate::Context; use crate::Item; @@ -57,7 +57,8 @@ impl FilterFactory for NonEmptyFilterFactory { } } -pub type NonEmptyFilterStatementFactory = FilterStatementFactory; +pub type NonEmptyFilterStatementFactory = + FilterStatementFactory; #[inline(always)] pub fn nonempty_filter() -> NonEmptyFilterStatementFactory { diff --git a/interpreter/src/lang/vocabulary/filters/unique.rs b/interpreter/src/lang/vocabulary/filters/unique.rs index 766a648..f1fb8ce 100644 --- a/interpreter/src/lang/vocabulary/filters/unique.rs +++ b/interpreter/src/lang/vocabulary/filters/unique.rs @@ -151,8 +151,7 @@ pub fn unique_field_filter() -> UniqueFieldFilterStatementFactory { UniqueFieldFilterStatementFactory::new(UniqueFilterFactory) } -pub type UniqueFilterStatementFactory = - FilterStatementFactory; +pub type UniqueFilterStatementFactory = FilterStatementFactory; #[inline(always)] pub fn unique_filter() -> UniqueFilterStatementFactory { diff --git a/interpreter/src/lang/vocabulary/item_ops/add.rs b/interpreter/src/lang/vocabulary/item_ops/add.rs index 36fbb7e..a27dc7b 100644 --- a/interpreter/src/lang/vocabulary/item_ops/add.rs +++ b/interpreter/src/lang/vocabulary/item_ops/add.rs @@ -35,9 +35,7 @@ impl ItemOp for AddItemOp { if let Type::Primitive(lhs) = &lhs { let rhs = self.rhs.execute(context)?; if let Type::Primitive(rhs) = &rhs { - Ok(Type::Primitive( - lhs.try_add(rhs).map_err(RuntimeMsg)?, - )) + Ok(Type::Primitive(lhs.try_add(rhs).map_err(RuntimeMsg)?)) } else { Err(RuntimeMsg(format!( "Cannot add right-hand side `{}` ({}): not primitive type", diff --git a/interpreter/src/lang/vocabulary/item_ops/field_assign.rs b/interpreter/src/lang/vocabulary/item_ops/field_assign.rs index 29546fb..764831f 100644 --- a/interpreter/src/lang/vocabulary/item_ops/field_assign.rs +++ b/interpreter/src/lang/vocabulary/item_ops/field_assign.rs @@ -78,7 +78,7 @@ impl ItemOpFactory for FieldAssignItemOpFactory { factory: &ItemBlockFactory, dict: &LanguageDictionary, ) -> Result { - let var_name =if tokens[0].is_dot() { + let var_name = if tokens[0].is_dot() { "item".to_string() } else { assert_token( diff --git a/interpreter/src/lang/vocabulary/item_ops/negate.rs b/interpreter/src/lang/vocabulary/item_ops/negate.rs index 0e0b450..20fb52c 100644 --- a/interpreter/src/lang/vocabulary/item_ops/negate.rs +++ b/interpreter/src/lang/vocabulary/item_ops/negate.rs @@ -32,9 +32,7 @@ impl ItemOp for NegateItemOp { fn execute(&self, context: &mut Context) -> Result { let rhs = self.rhs.execute(context)?; if let Type::Primitive(rhs) = &rhs { - Ok(Type::Primitive( - rhs.try_negate().map_err(RuntimeMsg)?, - )) + Ok(Type::Primitive(rhs.try_negate().map_err(RuntimeMsg)?)) } else { Err(RuntimeMsg(format!( "Cannot negate `{}` ({}): not primitive type", diff --git a/interpreter/src/lang/vocabulary/item_ops/not.rs b/interpreter/src/lang/vocabulary/item_ops/not.rs index e2a6b59..45c66f3 100644 --- a/interpreter/src/lang/vocabulary/item_ops/not.rs +++ b/interpreter/src/lang/vocabulary/item_ops/not.rs @@ -32,9 +32,7 @@ impl ItemOp for NotItemOp { fn execute(&self, context: &mut Context) -> Result { let rhs = self.rhs.execute(context)?; if let Type::Primitive(rhs) = &rhs { - Ok(Type::Primitive( - rhs.try_not().map_err(RuntimeMsg)?, - )) + Ok(Type::Primitive(rhs.try_not().map_err(RuntimeMsg)?)) } else { Err(RuntimeMsg(format!( "Cannot apply logical NOT to `{}` ({}): not primitive type", diff --git a/interpreter/src/lang/vocabulary/item_ops/subtract.rs b/interpreter/src/lang/vocabulary/item_ops/subtract.rs index d57b24a..e2480dd 100644 --- a/interpreter/src/lang/vocabulary/item_ops/subtract.rs +++ b/interpreter/src/lang/vocabulary/item_ops/subtract.rs @@ -35,9 +35,7 @@ impl ItemOp for SubtractItemOp { if let Type::Primitive(lhs) = &lhs { let rhs = self.rhs.execute(context)?; if let Type::Primitive(rhs) = &rhs { - Ok(Type::Primitive( - lhs.try_subtract(rhs).map_err(RuntimeMsg)?, - )) + Ok(Type::Primitive(lhs.try_subtract(rhs).map_err(RuntimeMsg)?)) } else { Err(RuntimeMsg(format!( "Cannot subtract right-hand side `{}` ({}): not primitive type", diff --git a/interpreter/src/lang/vocabulary/mpd_query.rs b/interpreter/src/lang/vocabulary/mpd_query.rs index 699b93e..e47ec15 100644 --- a/interpreter/src/lang/vocabulary/mpd_query.rs +++ b/interpreter/src/lang/vocabulary/mpd_query.rs @@ -6,11 +6,11 @@ use std::net::SocketAddr; use crate::tokens::Token; use crate::Context; -use crate::lang::{LanguageDictionary, repeated_tokens, Lookup}; -use crate::lang::{FunctionFactory, FunctionStatementFactory, IteratorItem, Op, PseudoOp}; -use crate::lang::{RuntimeError, SyntaxError, RuntimeOp}; use crate::lang::utility::{assert_token, assert_token_raw}; use crate::lang::TypePrimitive; +use crate::lang::{repeated_tokens, LanguageDictionary, Lookup}; +use crate::lang::{FunctionFactory, FunctionStatementFactory, IteratorItem, Op, PseudoOp}; +use crate::lang::{RuntimeError, RuntimeOp, SyntaxError}; use crate::processing::general::Type; use crate::Item; @@ -50,49 +50,61 @@ impl Iterator for MpdQueryStatement { //let ctx = self.context.as_mut().unwrap(); if self.results.is_none() { self.results = Some(VecDeque::with_capacity(0)); // in case of failure - // build address + // build address let addr_str = match self.addr.get(self.context.as_mut().unwrap()) { Ok(Type::Primitive(a)) => a.as_str(), - Ok(x) => return Some(Err( - RuntimeError { + Ok(x) => { + return Some(Err(RuntimeError { line: 0, msg: format!("Cannot use non-primitive `{}` as IP address", x), op: PseudoOp::from_printable(self), - } - )), + })) + } Err(e) => return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))), }; #[cfg(not(feature = "ergonomics"))] let addr: SocketAddr = match addr_str.parse() { Ok(a) => a, - Err(e) => return Some(Err(RuntimeError { - line: 0, - op: PseudoOp::from_printable(self), - msg: format!("Cannot convert `{}` to IP Address: {}", addr_str, e), - })) + Err(e) => { + return Some(Err(RuntimeError { + line: 0, + op: PseudoOp::from_printable(self), + msg: format!("Cannot convert `{}` to IP Address: {}", addr_str, e), + })) + } }; #[cfg(feature = "ergonomics")] let addr: SocketAddr = if addr_str.starts_with("localhost:") { let port_str = addr_str.replace("localhost:", ""); let port = match port_str.parse::() { Ok(p) => p, - Err(e) => return Some(Err(RuntimeError { - line: 0, - op: PseudoOp::from_printable(self), - msg: format!("Cannot convert `{}` to IP port: {}", port_str, e), - })) + Err(e) => { + return Some(Err(RuntimeError { + line: 0, + op: PseudoOp::from_printable(self), + msg: format!("Cannot convert `{}` to IP port: {}", port_str, e), + })) + } }; - SocketAddr::V4(std::net::SocketAddrV4::new(std::net::Ipv4Addr::LOCALHOST, port)) + SocketAddr::V4(std::net::SocketAddrV4::new( + std::net::Ipv4Addr::LOCALHOST, + port, + )) } else if addr_str == "default" { - SocketAddr::V4(std::net::SocketAddrV4::new(std::net::Ipv4Addr::LOCALHOST, 6600)) + SocketAddr::V4(std::net::SocketAddrV4::new( + std::net::Ipv4Addr::LOCALHOST, + 6600, + )) } else { match addr_str.parse() { Ok(a) => a, - Err(e) => return Some(Err(RuntimeError { - line: 0, - op: PseudoOp::from_printable(self), - msg: format!("Cannot convert `{}` to IP Address: {}", addr_str, e), - })) + Err(e) => { + return Some(Err(RuntimeError { + line: 0, + op: PseudoOp::from_printable(self), + msg: format!("Cannot convert `{}` to IP Address: {}", addr_str, e), + })) + } } }; // build params @@ -100,21 +112,29 @@ impl Iterator for MpdQueryStatement { for (term, value) in self.params.iter() { let static_val = match value.get(self.context.as_mut().unwrap()) { Ok(Type::Primitive(a)) => a.as_str(), - Ok(x) => return Some(Err( - RuntimeError { + Ok(x) => { + return Some(Err(RuntimeError { line: 0, msg: format!("Cannot use non-primitive `{}` MPS query value", x), op: PseudoOp::from_printable(self), - } - )), + })) + } Err(e) => return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))), }; new_params.push((term, static_val)); } - self.results = Some(match self.context.as_mut().unwrap().mpd_database.one_shot_search(addr, new_params) { - Ok(items) => items, - Err(e) => return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))) - }); + self.results = Some( + match self + .context + .as_mut() + .unwrap() + .mpd_database + .one_shot_search(addr, new_params) + { + Ok(items) => items, + Err(e) => return Some(Err(e.with(RuntimeOp(PseudoOp::from_printable(self))))), + }, + ); } let results = self.results.as_mut().unwrap(); results.pop_front().map(Ok) @@ -169,7 +189,10 @@ impl FunctionFactory for MpdQueryFunctionFactory { Ok(MpdQueryStatement { context: None, addr: addr_lookup, - params: vec![("any".to_string(), Lookup::Static(Type::Primitive(TypePrimitive::String("".to_owned()))))], + params: vec![( + "any".to_string(), + Lookup::Static(Type::Primitive(TypePrimitive::String("".to_owned()))), + )], results: None, }) } else { @@ -182,13 +205,15 @@ impl FunctionFactory for MpdQueryFunctionFactory { _ => None, }, Token::Name("term".to_string()), - tokens)?; + tokens, + )?; assert_token_raw(Token::Equals, tokens)?; let val = Lookup::parse(tokens)?; Ok(Some((term, val))) }, - Token::Comma - ).ingest_all(tokens)?; + Token::Comma, + ) + .ingest_all(tokens)?; Ok(MpdQueryStatement { context: None, addr: addr_lookup, @@ -200,7 +225,8 @@ impl FunctionFactory for MpdQueryFunctionFactory { } #[cfg(feature = "mpd")] -pub type MpdQueryStatementFactory = FunctionStatementFactory; +pub type MpdQueryStatementFactory = + FunctionStatementFactory; #[cfg(feature = "mpd")] #[inline(always)] diff --git a/interpreter/src/lang/vocabulary/repeat.rs b/interpreter/src/lang/vocabulary/repeat.rs index d87aeb2..48a0ef1 100644 --- a/interpreter/src/lang/vocabulary/repeat.rs +++ b/interpreter/src/lang/vocabulary/repeat.rs @@ -8,9 +8,7 @@ use crate::Item; use crate::lang::utility::{assert_token, assert_token_raw}; use crate::lang::LanguageDictionary; -use crate::lang::{ - FunctionFactory, FunctionStatementFactory, IteratorItem, Op, PseudoOp, -}; +use crate::lang::{FunctionFactory, FunctionStatementFactory, IteratorItem, Op, PseudoOp}; use crate::lang::{RuntimeError, SyntaxError}; #[derive(Debug)] @@ -285,8 +283,7 @@ fn next_comma(tokens: &VecDeque) -> usize { tokens.len() } -pub type RepeatStatementFactory = - FunctionStatementFactory; +pub type RepeatStatementFactory = FunctionStatementFactory; #[inline(always)] pub fn repeat_function_factory() -> RepeatStatementFactory { diff --git a/interpreter/src/lang/vocabulary/sorters/bliss_next_sorter.rs b/interpreter/src/lang/vocabulary/sorters/bliss_next_sorter.rs index 0ef4652..8423b11 100644 --- a/interpreter/src/lang/vocabulary/sorters/bliss_next_sorter.rs +++ b/interpreter/src/lang/vocabulary/sorters/bliss_next_sorter.rs @@ -5,7 +5,7 @@ use std::fmt::{Debug, Display, Error, Formatter}; use crate::lang::utility::{assert_name, check_name}; use crate::lang::SyntaxError; #[cfg(feature = "advanced")] -use crate::lang::{IteratorItem, Op, Sorter, RuntimeMsg}; +use crate::lang::{IteratorItem, Op, RuntimeMsg, Sorter}; use crate::lang::{LanguageDictionary, SortStatementFactory, SorterFactory}; use crate::tokens::Token; #[cfg(feature = "advanced")] diff --git a/interpreter/src/lang/vocabulary/sorters/bliss_sorter.rs b/interpreter/src/lang/vocabulary/sorters/bliss_sorter.rs index 7eb8cf9..516d0ff 100644 --- a/interpreter/src/lang/vocabulary/sorters/bliss_sorter.rs +++ b/interpreter/src/lang/vocabulary/sorters/bliss_sorter.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use crate::lang::utility::{assert_name, check_name}; use crate::lang::SyntaxError; #[cfg(feature = "advanced")] -use crate::lang::{IteratorItem, Op, Sorter, RuntimeMsg}; +use crate::lang::{IteratorItem, Op, RuntimeMsg, Sorter}; use crate::lang::{LanguageDictionary, SortStatementFactory, SorterFactory}; use crate::tokens::Token; #[cfg(feature = "advanced")] diff --git a/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs b/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs index c6aa769..afa065f 100644 --- a/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs +++ b/interpreter/src/lang/vocabulary/sorters/empty_sorter.rs @@ -2,8 +2,8 @@ use std::collections::VecDeque; use std::fmt::{Debug, Display, Error, Formatter}; use crate::lang::{IteratorItem, LanguageDictionary, Op}; -use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::lang::{RuntimeMsg, SyntaxError}; +use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::tokens::Token; #[derive(Debug, Clone, Default)] diff --git a/interpreter/src/lang/vocabulary/sorters/field_sorter.rs b/interpreter/src/lang/vocabulary/sorters/field_sorter.rs index 54d422d..5d1b5ef 100644 --- a/interpreter/src/lang/vocabulary/sorters/field_sorter.rs +++ b/interpreter/src/lang/vocabulary/sorters/field_sorter.rs @@ -4,8 +4,8 @@ use std::fmt::{Debug, Display, Error, Formatter}; use crate::lang::utility::assert_token; use crate::lang::{IteratorItem, LanguageDictionary, Op}; -use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::lang::{RuntimeMsg, SyntaxError}; +use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::tokens::Token; #[derive(Debug, Clone)] diff --git a/interpreter/src/lang/vocabulary/sorters/shuffle.rs b/interpreter/src/lang/vocabulary/sorters/shuffle.rs index 074c0e6..98a5d19 100644 --- a/interpreter/src/lang/vocabulary/sorters/shuffle.rs +++ b/interpreter/src/lang/vocabulary/sorters/shuffle.rs @@ -5,8 +5,8 @@ use rand::{thread_rng, Rng}; use crate::lang::utility::{assert_name, check_name}; use crate::lang::{IteratorItem, LanguageDictionary, Op}; -use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::lang::{RuntimeMsg, SyntaxError}; +use crate::lang::{SortStatementFactory, Sorter, SorterFactory}; use crate::tokens::Token; const RNG_LIMIT_BITMASK: usize = 0xffff; // bits to preserve in RNG @@ -90,8 +90,7 @@ impl SorterFactory for ShuffleSorterFactory { } } -pub type ShuffleSorterStatementFactory = - SortStatementFactory; +pub type ShuffleSorterStatementFactory = SortStatementFactory; #[inline(always)] pub fn shuffle_sort() -> ShuffleSorterStatementFactory { diff --git a/interpreter/src/lang/vocabulary/sql_query.rs b/interpreter/src/lang/vocabulary/sql_query.rs index 399f502..fea7ae0 100644 --- a/interpreter/src/lang/vocabulary/sql_query.rs +++ b/interpreter/src/lang/vocabulary/sql_query.rs @@ -4,8 +4,7 @@ use std::iter::Iterator; use crate::lang::utility::assert_token; use crate::lang::{ - FunctionFactory, FunctionStatementFactory, IteratorItem, LanguageDictionary, Op, - PseudoOp, + FunctionFactory, FunctionStatementFactory, IteratorItem, LanguageDictionary, Op, PseudoOp, }; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; use crate::tokens::Token; diff --git a/interpreter/src/lang/vocabulary/sql_simple_query.rs b/interpreter/src/lang/vocabulary/sql_simple_query.rs index 1366c0e..8a8f387 100644 --- a/interpreter/src/lang/vocabulary/sql_simple_query.rs +++ b/interpreter/src/lang/vocabulary/sql_simple_query.rs @@ -4,8 +4,7 @@ use std::iter::Iterator; use crate::lang::utility::assert_token; use crate::lang::{ - FunctionFactory, FunctionStatementFactory, IteratorItem, LanguageDictionary, Op, - PseudoOp, + FunctionFactory, FunctionStatementFactory, IteratorItem, LanguageDictionary, Op, PseudoOp, }; use crate::lang::{RuntimeError, RuntimeMsg, RuntimeOp, SyntaxError}; use crate::tokens::Token; diff --git a/interpreter/src/lang/vocabulary/variable_assign.rs b/interpreter/src/lang/vocabulary/variable_assign.rs index e9021ec..b986732 100644 --- a/interpreter/src/lang/vocabulary/variable_assign.rs +++ b/interpreter/src/lang/vocabulary/variable_assign.rs @@ -7,9 +7,7 @@ use crate::Context; use crate::lang::utility::{assert_token, assert_token_raw, assert_type, check_is_type}; use crate::lang::LanguageDictionary; -use crate::lang::{ - BoxedOpFactory, IteratorItem, Op, OpFactory, TypePrimitive, PseudoOp, -}; +use crate::lang::{BoxedOpFactory, IteratorItem, Op, OpFactory, PseudoOp, TypePrimitive}; use crate::lang::{RuntimeError, RuntimeOp, SyntaxError}; use crate::processing::general::Type; @@ -75,15 +73,13 @@ impl Iterator for AssignStatement { Err(e) => return Some(Err(e)), }; let result = if self.is_declaration { - self - .context + self.context .as_mut() .unwrap() .variables .declare(&self.variable_name, Type::Op(real)) } else { - self - .context + self.context .as_mut() .unwrap() .variables @@ -107,15 +103,13 @@ impl Iterator for AssignStatement { } else { let assign_type = self.assign_type.clone().unwrap(); let result = if self.is_declaration { - self - .context + self.context .as_mut() .unwrap() .variables .declare(&self.variable_name, Type::Primitive(assign_type)) } else { - self - .context + self.context .as_mut() .unwrap() .variables diff --git a/interpreter/src/music/build_library.rs b/interpreter/src/music/build_library.rs index 40c7277..4a72794 100644 --- a/interpreter/src/music/build_library.rs +++ b/interpreter/src/music/build_library.rs @@ -3,10 +3,7 @@ use std::path::Path; use super::Library; use crate::lang::db::*; -pub fn build_library_from_files>( - path: P, - lib: &mut Library, -) -> std::io::Result<()> { +pub fn build_library_from_files>(path: P, lib: &mut Library) -> std::io::Result<()> { //let mut result = Library::new(); lib.read_path(path, 10)?; Ok(()) diff --git a/interpreter/src/music/library.rs b/interpreter/src/music/library.rs index 2a23e5a..8ac7425 100644 --- a/interpreter/src/music/library.rs +++ b/interpreter/src/music/library.rs @@ -71,7 +71,7 @@ impl Library { self.songs.insert(song.song_id, song); } - pub fn all_metadata(& self) -> Vec<&'_ DbMetaItem> { + pub fn all_metadata(&self) -> Vec<&'_ DbMetaItem> { self.metadata.values().collect() } diff --git a/interpreter/src/music/tag.rs b/interpreter/src/music/tag.rs index fc3440d..692ec0e 100644 --- a/interpreter/src/music/tag.rs +++ b/interpreter/src/music/tag.rs @@ -149,7 +149,9 @@ impl Tags { pub fn artist(&self, id: u64, genre_id: u64) -> DbArtistItem { DbArtistItem { artist_id: id, - name: self.artist_name().unwrap_or_else(|| "Unknown Artist".into()), + name: self + .artist_name() + .unwrap_or_else(|| "Unknown Artist".into()), genre: genre_id, } } diff --git a/interpreter/src/processing/filesystem.rs b/interpreter/src/processing/filesystem.rs index a9642d6..92c8222 100644 --- a/interpreter/src/processing/filesystem.rs +++ b/interpreter/src/processing/filesystem.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use regex::Regex; -use crate::lang::{TypePrimitive, RuntimeMsg}; +use crate::lang::{RuntimeMsg, TypePrimitive}; use crate::Item; const DEFAULT_REGEX: &str = r"/(?P[^/]+)/(?P[^/]+)/(?:(?:(?P\d+)\s+)?(?P\d+)\.?\s+)?(?P[^/]+)\.(?P<format>(?:mp3)|(?:wav)|(?:ogg)|(?:flac)|(?:mp4)|(?:aac))$"; @@ -41,7 +41,8 @@ impl Iterator for SortedReadDir { } } self.dir_iter_complete = true; - self.cache.sort_by_key(|b| std::cmp::Reverse(b.path().to_string_lossy().to_lowercase())); + self.cache + .sort_by_key(|b| std::cmp::Reverse(b.path().to_string_lossy().to_lowercase())); /*self.cache.sort_by( |a, b| b.path().to_string_lossy().to_lowercase().cmp( &a.path().to_string_lossy().to_lowercase()) @@ -227,7 +228,7 @@ impl FileIter { if let Some(captures) = captures { for name in capture_names.flatten() { if item.field(name).is_some() { - // do nothing + // do nothing } else if let Some(value) = captures.name(name).map(|m| m.as_str().to_string()) { item.set_field(name, TypePrimitive::parse(value)); } diff --git a/interpreter/src/processing/mod.rs b/interpreter/src/processing/mod.rs index abb1ff6..7e897f8 100644 --- a/interpreter/src/processing/mod.rs +++ b/interpreter/src/processing/mod.rs @@ -1,17 +1,17 @@ mod filesystem; -#[cfg(feature = "advanced")] -mod music_analysis; #[cfg(feature = "mpd")] mod mpd; +#[cfg(feature = "advanced")] +mod music_analysis; mod sql; mod variables; //pub type OpGetter = dyn FnMut() -> crate::lang::PseudoOp; pub mod database { - pub use super::sql::{DatabaseQuerier, SQLiteExecutor, QueryResult}; #[cfg(feature = "mpd")] - pub use super::mpd::{MpdQuerier, MpdExecutor}; + pub use super::mpd::{MpdExecutor, MpdQuerier}; + pub use super::sql::{DatabaseQuerier, QueryResult, SQLiteExecutor}; } pub mod general { diff --git a/interpreter/src/processing/mpd.rs b/interpreter/src/processing/mpd.rs index 0fccc5f..14b0f8b 100644 --- a/interpreter/src/processing/mpd.rs +++ b/interpreter/src/processing/mpd.rs @@ -1,14 +1,14 @@ use core::fmt::Debug; use std::collections::VecDeque; -use std::net::{SocketAddr, TcpStream}; use std::iter::Iterator; +use std::net::{SocketAddr, TcpStream}; use mpd::Client; -use mpd::{Query, Term, Song}; +use mpd::{Query, Song, Term}; use crate::lang::RuntimeMsg; -use crate::Item; use crate::lang::TypePrimitive; +use crate::Item; /// Music Player Daemon interface for interacting with it's database pub trait MpdQuerier: Debug { @@ -16,7 +16,11 @@ pub trait MpdQuerier: Debug { fn search(&mut self, params: Vec<(&str, String)>) -> Result<VecDeque<Item>, RuntimeMsg>; - fn one_shot_search(&self, addr: SocketAddr, params: Vec<(&str, String)>) -> Result<VecDeque<Item>, RuntimeMsg>; + fn one_shot_search( + &self, + addr: SocketAddr, + params: Vec<(&str, String)>, + ) -> Result<VecDeque<Item>, RuntimeMsg>; } #[derive(Default, Debug)] @@ -26,7 +30,10 @@ pub struct MpdExecutor { impl MpdQuerier for MpdExecutor { fn connect(&mut self, addr: SocketAddr) -> Result<(), RuntimeMsg> { - self.connection = Some(Client::connect(addr).map_err(|e| RuntimeMsg(format!("MPD connection error: {}", e)))?); + self.connection = Some( + Client::connect(addr) + .map_err(|e| RuntimeMsg(format!("MPD connection error: {}", e)))?, + ); Ok(()) } @@ -40,19 +47,31 @@ impl MpdQuerier for MpdExecutor { for (term, value) in params { query_mut = query_mut.and(str_to_term(term), value); } - let songs = self.connection.as_mut().unwrap().search(query_mut, None).map_err(|e| RuntimeMsg(format!("MPD search error: {}", e)))?; + let songs = self + .connection + .as_mut() + .unwrap() + .search(query_mut, None) + .map_err(|e| RuntimeMsg(format!("MPD search error: {}", e)))?; Ok(songs.into_iter().map(song_to_item).collect()) } - fn one_shot_search(&self, addr: SocketAddr, params: Vec<(&str, String)>) -> Result<VecDeque<Item>, RuntimeMsg> { - let mut connection = Client::connect(addr).map_err(|e| RuntimeMsg(format!("MPD connection error: {}", e)))?; + fn one_shot_search( + &self, + addr: SocketAddr, + params: Vec<(&str, String)>, + ) -> Result<VecDeque<Item>, RuntimeMsg> { + let mut connection = Client::connect(addr) + .map_err(|e| RuntimeMsg(format!("MPD connection error: {}", e)))?; //let music_dir = connection.music_directory().map_err(|e| RuntimeMsg(format!("MPD command error: {}", e)))?; let mut query = Query::new(); let mut query_mut = &mut query; for (term, value) in params { query_mut = query_mut.and(str_to_term(term), value); } - let songs = connection.search(query_mut, None).map_err(|e| RuntimeMsg(format!("MPD search error: {}", e)))?; + let songs = connection + .search(query_mut, None) + .map_err(|e| RuntimeMsg(format!("MPD search error: {}", e)))?; Ok(songs.into_iter().map(song_to_item).collect()) } } @@ -101,6 +120,6 @@ fn str_to_term(s: &str) -> Term<'_> { "file" => Term::File, "base" => Term::Base, "lastmod" => Term::LastMod, - x => Term::Tag(x.into()) + x => Term::Tag(x.into()), } } diff --git a/interpreter/src/processing/music_analysis.rs b/interpreter/src/processing/music_analysis.rs index 7e80764..51264ed 100644 --- a/interpreter/src/processing/music_analysis.rs +++ b/interpreter/src/processing/music_analysis.rs @@ -58,12 +58,7 @@ impl std::default::Default for DefaultAnalyzer { #[cfg(feature = "bliss-audio-symphonia")] impl DefaultAnalyzer { - fn request_distance( - &mut self, - from: &Item, - to: &Item, - ack: bool, - ) -> Result<(), RuntimeMsg> { + fn request_distance(&mut self, from: &Item, to: &Item, ack: bool) -> Result<(), RuntimeMsg> { let path_from = Self::get_path(from)?; let path_to = Self::get_path(to)?; self.requests @@ -89,7 +84,6 @@ impl DefaultAnalyzer { PATH_FIELD, path ))) } - } else { Err(RuntimeMsg(format!( "Field {} on item is not String, it's {}", @@ -141,7 +135,7 @@ impl MusicAnalyzer for DefaultAnalyzer { }; } } - ResponseType::Song { .. } => {}, + ResponseType::Song { .. } => {} ResponseType::UnsupportedSong { path, msg } => { if path == path_to || path == path_from { return Err(RuntimeMsg(format!("Bliss error: {}", msg))); @@ -213,7 +207,7 @@ enum ResponseType { UnsupportedSong { path: String, msg: String, - } + }, } #[cfg(feature = "bliss-audio-symphonia")] @@ -248,11 +242,11 @@ impl CacheThread { distance, } => { self.insert_distance(path1, path2, distance); - }, + } ResponseType::Song { path, song } => { self.insert_song(path, song); - }, - ResponseType::UnsupportedSong { .. } => {}, + } + ResponseType::UnsupportedSong { .. } => {} } } } @@ -263,7 +257,8 @@ impl CacheThread { // avoid using too much memory -- songs are big memory objects self.song_cache.clear(); } - self.song_cache.insert(path, song_result.map(|x| x.as_ref().to_owned())); + self.song_cache + .insert(path, song_result.map(|x| x.as_ref().to_owned())); } fn insert_distance( @@ -309,8 +304,11 @@ impl CacheThread { } else { self.insert_song(path2, song); } - }, - ResponseType::UnsupportedSong {path: unsupported_path, ..} => { + } + ResponseType::UnsupportedSong { + path: unsupported_path, + .. + } => { self.song_in_progress.remove(&unsupported_path); if path == unsupported_path { return None; @@ -319,10 +317,7 @@ impl CacheThread { } } } else if self.song_cache.contains_key(path) { - let result = self - .song_cache - .get(path) - .and_then(|r| r.clone().ok()); + let result = self.song_cache.get(path).and_then(|r| r.clone().ok()); if result.is_none() && auto_add { self.song_in_progress.insert(path.to_owned()); } @@ -346,11 +341,15 @@ impl CacheThread { if let Some(result) = self.distance_cache.get(&key) { if ack { let result = result.to_owned(); - if self.responses.send(ResponseType::Distance { - path1: path1, - path2: path2, - distance: result, - }).is_err() { + if self + .responses + .send(ResponseType::Distance { + path1: path1, + path2: path2, + distance: result, + }) + .is_err() + { return true; } } @@ -360,17 +359,26 @@ impl CacheThread { // also prevents deadlock in self.get_song_option() // due to waiting on song that isn't being processed yet // (first call adds it to song_in_progress set, second call just waits) - if ack && self.responses.send(ResponseType::Distance { - path1: path1, - path2: path2, - distance: Ok(0.0), - }).is_err() { + if ack + && self + .responses + .send(ResponseType::Distance { + path1: path1, + path2: path2, + distance: Ok(0.0), + }) + .is_err() + { return true; } } else if !self.distance_in_progress.contains(&key) { // distance worker uses 3 threads (it's own thread + 1 extra per song) for 2 songs - let available_parallelism = - (std::thread::available_parallelism().ok().map(|x| x.get()).unwrap_or(DEFAULT_PARALLELISM) * 2) / 3; + let available_parallelism = (std::thread::available_parallelism() + .ok() + .map(|x| x.get()) + .unwrap_or(DEFAULT_PARALLELISM) + * 2) + / 3; let available_parallelism = if available_parallelism != 0 { available_parallelism - 1 } else { @@ -386,14 +394,17 @@ impl CacheThread { distance, } => { self.insert_distance(path1, path2, distance); - }, + } ResponseType::Song { path: path2, song } => { self.insert_song(path2.clone(), song.clone()); if self.song_in_progress.len() <= available_parallelism { break 'inner4; } - }, - ResponseType::UnsupportedSong {path: unsupported_path, ..} => { + } + ResponseType::UnsupportedSong { + path: unsupported_path, + .. + } => { self.song_in_progress.remove(&unsupported_path); if self.song_in_progress.len() <= available_parallelism { break 'inner4; @@ -431,11 +442,15 @@ impl CacheThread { distance.clone(), ); if path1_2 == key.0 && path2_2 == key.1 { - if self.responses.send(ResponseType::Distance { - path1: path1_2, - path2: path2_2, - distance: distance, - }).is_err() { + if self + .responses + .send(ResponseType::Distance { + path1: path1_2, + path2: path2_2, + distance: distance, + }) + .is_err() + { return true; } break 'inner1; @@ -443,13 +458,20 @@ impl CacheThread { } ResponseType::Song { path, song } => { self.insert_song(path, song); - }, - ResponseType::UnsupportedSong { path: unsupported_path, msg } => { + } + ResponseType::UnsupportedSong { + path: unsupported_path, + msg, + } => { self.song_in_progress.remove(&unsupported_path); - if self.responses.send(ResponseType::UnsupportedSong { - path: unsupported_path.clone(), - msg: msg - }).is_err() { + if self + .responses + .send(ResponseType::UnsupportedSong { + path: unsupported_path.clone(), + msg: msg, + }) + .is_err() + { return true; } if unsupported_path == key.0 || unsupported_path == key.1 { @@ -476,10 +498,14 @@ impl CacheThread { } else if !path.contains("://") { path } else { - if self.responses.send(ResponseType::UnsupportedSong { - msg: format!("Song path is not a supported URI, it's `{}`", path), - path: path, - }).is_err() { + if self + .responses + .send(ResponseType::UnsupportedSong { + msg: format!("Song path is not a supported URI, it's `{}`", path), + path: path, + }) + .is_err() + { return true; } return false; @@ -487,18 +513,25 @@ impl CacheThread { if let Some(song) = self.song_cache.get(&path) { if ack { let song = song.to_owned(); - if self.responses.send(ResponseType::Song { - path: path, - song: song.map(Box::new), - }).is_err() { + if self + .responses + .send(ResponseType::Song { + path: path, + song: song.map(Box::new), + }) + .is_err() + { return true; } } } else { if !self.song_in_progress.contains(&path) { // every song is roughly 2 threads -- Song::from_path(...) spawns a thread - let available_parallelism = - std::thread::available_parallelism().ok().map(|x| x.get()).unwrap_or(DEFAULT_PARALLELISM) / 2; + let available_parallelism = std::thread::available_parallelism() + .ok() + .map(|x| x.get()) + .unwrap_or(DEFAULT_PARALLELISM) + / 2; let available_parallelism = if available_parallelism != 0 { available_parallelism - 1 } else { @@ -520,7 +553,7 @@ impl CacheThread { if self.song_in_progress.len() <= available_parallelism { break 'inner2; } - }, + } ResponseType::UnsupportedSong { path, .. } => { self.song_in_progress.remove(&path); if self.song_in_progress.len() <= available_parallelism { @@ -555,22 +588,33 @@ impl CacheThread { ResponseType::Song { path: path2, song } => { self.insert_song(path2.clone(), song.clone()); if path2 == path { - if self.responses.send(ResponseType::Song { - path: path, - song: song, - }).is_err() { + if self + .responses + .send(ResponseType::Song { + path: path, + song: song, + }) + .is_err() + { return true; } break 'inner3; } } - ResponseType::UnsupportedSong { path: unsupported_path, msg } => { + ResponseType::UnsupportedSong { + path: unsupported_path, + msg, + } => { self.song_in_progress.remove(&unsupported_path); if unsupported_path == path { - if self.responses.send(ResponseType::UnsupportedSong { - path: unsupported_path, - msg: msg - }).is_err() { + if self + .responses + .send(ResponseType::UnsupportedSong { + path: unsupported_path, + msg: msg, + }) + .is_err() + { return true; } break 'inner3; @@ -639,7 +683,11 @@ fn worker_distance( }) .unwrap_or(()); if new_song2.is_err() { - eprintln!("Song error on `{}`: {}", path2, new_song2.clone().err().unwrap()); + eprintln!( + "Song error on `{}`: {}", + path2, + new_song2.clone().err().unwrap() + ); } new_song2? }; diff --git a/interpreter/src/processing/sql.rs b/interpreter/src/processing/sql.rs index 7a53528..4c71d58 100644 --- a/interpreter/src/processing/sql.rs +++ b/interpreter/src/processing/sql.rs @@ -1,6 +1,6 @@ use core::fmt::Debug; -use std::fmt::Write; use std::collections::{HashMap, HashSet}; +use std::fmt::Write; use crate::lang::db::*; use crate::lang::RuntimeMsg; diff --git a/interpreter/src/processing/variables.rs b/interpreter/src/processing/variables.rs index b307b95..17021a5 100644 --- a/interpreter/src/processing/variables.rs +++ b/interpreter/src/processing/variables.rs @@ -3,8 +3,8 @@ use std::fmt::{Debug, Display, Error, Formatter}; use std::collections::HashMap; use crate::lang::Op; -use crate::lang::TypePrimitive; use crate::lang::RuntimeMsg; +use crate::lang::TypePrimitive; use crate::Item; #[derive(Debug)] diff --git a/interpreter/src/tokens/tokenizer.rs b/interpreter/src/tokens/tokenizer.rs index c00a16c..5e62736 100644 --- a/interpreter/src/tokens/tokenizer.rs +++ b/interpreter/src/tokens/tokenizer.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; -use super::Token; use super::ParseError; +use super::Token; pub trait TokenReader { fn current_line(&self) -> usize; diff --git a/interpreter/tests/single_line.rs b/interpreter/tests/single_line.rs index b9dae26..1a3f50d 100644 --- a/interpreter/tests/single_line.rs +++ b/interpreter/tests/single_line.rs @@ -1,6 +1,6 @@ //! Integration tests for every syntax feature -use muss_interpreter::tokens::{Token, Tokenizer, ParseError}; +use muss_interpreter::tokens::{ParseError, Token, Tokenizer}; use muss_interpreter::*; use std::collections::VecDeque; use std::io::Cursor; @@ -823,45 +823,21 @@ fn execute_emptiesop_line() -> Result<(), InterpreterError> { #[test] fn execute_nonemptyfilter_line() -> Result<(), InterpreterError> { - execute_single_line( - "files().(??)", - false, - true, - )?; - execute_single_line( - "empties(42).(??)", - true, - true, - ) + execute_single_line("files().(??)", false, true)?; + execute_single_line("empties(42).(??)", true, true) } #[test] fn execute_mpdfunction_line() -> Result<(), InterpreterError> { - execute_single_line( - "mpd(`127.0.0.1:6600`, artist=`Bruno Mars`)", - false, - true, - )?; + execute_single_line("mpd(`127.0.0.1:6600`, artist=`Bruno Mars`)", false, true)?; execute_single_line( "mpd(`127.0.0.1:6600`, title=`something very long that should match absolutely nothing, probably, hopefully...`)", true, true, )?; #[cfg(feature = "ergonomics")] - execute_single_line( - "mpd(`localhost:6600`)", - false, - true, - )?; + execute_single_line("mpd(`localhost:6600`)", false, true)?; #[cfg(feature = "ergonomics")] - execute_single_line( - "mpd(`default`)", - false, - true, - )?; - execute_single_line( - "mpd(`127.0.0.1:6600`)", - false, - true, - ) + execute_single_line("mpd(`default`)", false, true)?; + execute_single_line("mpd(`127.0.0.1:6600`)", false, true) } diff --git a/m3u8/src/main.rs b/m3u8/src/main.rs index de8e74a..7841525 100644 --- a/m3u8/src/main.rs +++ b/m3u8/src/main.rs @@ -33,9 +33,7 @@ fn main() { for item in runner { match item { Ok(music) => { - if let Some(filename) = - music_filename(&music) - { + if let Some(filename) = music_filename(&music) { playlist.segments.push(MediaSegment { uri: filename, title: music_title(&music), @@ -56,9 +54,7 @@ fn main() { for item in runner { match item { Ok(music) => { - if let Some(filename) = - music_filename(&music) - { + if let Some(filename) = music_filename(&music) { playlist.segments.push(MediaSegment { uri: filename, title: music_title(&music), @@ -99,5 +95,3 @@ fn music_filename(item: &Item) -> Option<String> { None } } - - diff --git a/player/src/controller.rs b/player/src/controller.rs index 362e845..288111b 100644 --- a/player/src/controller.rs +++ b/player/src/controller.rs @@ -1,12 +1,12 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread::JoinHandle; -use muss_interpreter::{Item, InterpreterError}; +use muss_interpreter::{InterpreterError, Item}; use super::os_controls::SystemControlWrapper; -use super::player_wrapper::{ControlAction, PlayerServer, PlayerAction}; -use super::Player; +use super::player_wrapper::{ControlAction, PlayerAction, PlayerServer}; use super::PlaybackError; +use super::Player; use super::PlayerError; /// A controller for a Player running on another thread. @@ -21,7 +21,7 @@ pub struct Controller { impl Controller { pub fn create< F: FnOnce() -> Player<I> + Send + 'static, - I: std::iter::Iterator<Item=Result<Item, InterpreterError>>, + I: std::iter::Iterator<Item = Result<Item, InterpreterError>>, >( player_gen: F, ) -> Self { @@ -48,7 +48,7 @@ impl Controller { pub fn create_repl< F: FnOnce() -> Player<I> + Send + 'static, - I: std::iter::Iterator<Item=Result<Item, InterpreterError>>, + I: std::iter::Iterator<Item = Result<Item, InterpreterError>>, >( player_gen: F, ) -> Self { @@ -87,14 +87,15 @@ impl Controller { Ok(()) } else { Err(PlaybackError { - msg: "Incorrect acknowledgement received for Controller control action" - .into(), - }.into()) + msg: "Incorrect acknowledgement received for Controller control action".into(), + } + .into()) } } else { Err(PlaybackError { msg: "Invalid acknowledgement received for Controller control action".into(), - }.into()) + } + .into()) } } @@ -146,7 +147,8 @@ impl Controller { Ok(x) => Ok(x), Err(_) => Err(PlaybackError { msg: "PlayerServer did not exit correctly".into(), - }.into()), + } + .into()), } } @@ -208,10 +210,13 @@ impl Controller { if action == to_send { break; } else { - result.push(PlaybackError { - msg: "Incorrect acknowledgement received for Controller control action" - .into(), - }.into()); + result.push( + PlaybackError { + msg: "Incorrect acknowledgement received for Controller control action" + .into(), + } + .into(), + ); } } else if let Err(e) = self.handle_event(msg) { result.push(e); diff --git a/player/src/errors.rs b/player/src/errors.rs index 6640a84..a2f1846 100644 --- a/player/src/errors.rs +++ b/player/src/errors.rs @@ -1,5 +1,5 @@ -use std::fmt::{Debug, Display, Error, Formatter}; use std::convert::From; +use std::fmt::{Debug, Display, Error, Formatter}; #[derive(Debug, Clone)] pub enum PlayerError { @@ -67,7 +67,7 @@ impl From<PlaybackError> for PlayerError { #[derive(Debug, Clone)] pub enum UriError { Unsupported(String), - Message(String) + Message(String), } impl UriError { @@ -81,7 +81,7 @@ impl Display for UriError { write!(f, "UriError: ")?; match self { Self::Unsupported(scheme) => write!(f, "Unsupported URI `{}//`", scheme), - Self::Message(msg) => write!(f, "{}", msg) + Self::Message(msg) => write!(f, "{}", msg), } } } diff --git a/player/src/lib.rs b/player/src/lib.rs index 6cbf25f..68f1dbf 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -15,10 +15,10 @@ pub(crate) mod uri; //mod utility; pub use controller::Controller; -pub use errors::{PlaybackError, UriError, PlayerError}; -pub use player::Player; +pub use errors::{PlaybackError, PlayerError, UriError}; #[cfg(feature = "mpd")] pub use player::mpd_connection; +pub use player::Player; //pub use utility::{play_script}; #[cfg(test)] diff --git a/player/src/os_controls.rs b/player/src/os_controls.rs index 8fd8cc4..eb0d31a 100644 --- a/player/src/os_controls.rs +++ b/player/src/os_controls.rs @@ -179,9 +179,7 @@ impl SystemControlWrapper { fn enqueued(item: Item, dbus_ctrl: &Sender<DbusControl>) { //println!("Got enqueued item {}", &item.title); - let file_uri = item - .field("filename") - .and_then(|x| x.to_owned().to_str()); + let file_uri = item.field("filename").and_then(|x| x.to_owned().to_str()); dbus_ctrl .send(DbusControl::SetMetadata(Metadata { length: None, diff --git a/player/src/player.rs b/player/src/player.rs index 1ea2d8b..158659d 100644 --- a/player/src/player.rs +++ b/player/src/player.rs @@ -6,11 +6,11 @@ use rodio::{decoder::Decoder, OutputStream, OutputStreamHandle, Sink}; use m3u8_rs::{MediaPlaylist, MediaSegment}; #[cfg(feature = "mpd")] -use mpd::{Client, Song, error}; +use mpd::{error, Client, Song}; use super::uri::Uri; -use muss_interpreter::{Item, InterpreterError}; +use muss_interpreter::{InterpreterError, Item}; //use super::PlaybackError; use super::PlayerError; @@ -20,7 +20,7 @@ use super::UriError; /// Playback functionality for a script. /// This takes the output of the runner and plays or saves it. -pub struct Player<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> { +pub struct Player<I: std::iter::Iterator<Item = Result<Item, InterpreterError>>> { runner: I, sink: Sink, #[allow(dead_code)] @@ -30,7 +30,7 @@ pub struct Player<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> { mpd_connection: Option<Client<std::net::TcpStream>>, } -impl<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> Player<I> { +impl<I: std::iter::Iterator<Item = Result<Item, InterpreterError>>> Player<I> { pub fn new(runner: I) -> Result<Self, PlayerError> { let (stream, output_handle) = OutputStream::try_default().map_err(PlayerError::from_err_playback)?; @@ -166,9 +166,7 @@ impl<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> Player<I> { for item in &mut self.runner { match item { Ok(music) => { - if let Some(filename) = - music_filename(&music) - { + if let Some(filename) = music_filename(&music) { //println!("Adding file `{}` to playlist", filename); playlist.segments.push(MediaSegment { uri: filename, @@ -215,12 +213,13 @@ impl<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> Player<I> { match uri.scheme() { Some(s) => match &s.to_lowercase() as &str { "file:" => { - let file = fs::File::open(uri.path()).map_err(PlayerError::from_err_playback)?; + let file = + fs::File::open(uri.path()).map_err(PlayerError::from_err_playback)?; let stream = io::BufReader::new(file); let source = Decoder::new(stream).map_err(PlayerError::from_err_playback)?; self.sink.append(source); Ok(()) - }, + } #[cfg(feature = "mpd")] "mpd:" => { if let Some(mpd_client) = &mut self.mpd_connection { @@ -229,13 +228,17 @@ impl<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> Player<I> { file: uri.path().to_owned(), ..Default::default() }; - mpd_client.push(song).map_err(PlayerError::from_err_playback)?; + mpd_client + .push(song) + .map_err(PlayerError::from_err_playback)?; Ok(()) } else { - Err(PlayerError::from_err_playback("Cannot play MPD song: no MPD client connected")) + Err(PlayerError::from_err_playback( + "Cannot play MPD song: no MPD client connected", + )) } - }, - scheme => Err(UriError::Unsupported(scheme.to_owned()).into()) + } + scheme => Err(UriError::Unsupported(scheme.to_owned()).into()), }, None => { //default diff --git a/player/src/player_wrapper.rs b/player/src/player_wrapper.rs index 7aa601b..3664414 100644 --- a/player/src/player_wrapper.rs +++ b/player/src/player_wrapper.rs @@ -2,7 +2,7 @@ use std::sync::mpsc::{Receiver, Sender}; use std::{thread, thread::JoinHandle}; //use muss_interpreter::tokens::TokenReader; -use muss_interpreter::{Item, InterpreterError}; +use muss_interpreter::{InterpreterError, Item}; use super::Player; use super::PlayerError; @@ -11,7 +11,7 @@ use super::PlayerError; /// This allows for message passing between the player and controller. /// /// You will probably never directly interact with this, instead using Controller to communicate. -pub struct PlayerServer<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> { +pub struct PlayerServer<I: std::iter::Iterator<Item = Result<Item, InterpreterError>>> { player: Player<I>, control: Receiver<ControlAction>, event: Sender<PlayerAction>, @@ -19,7 +19,7 @@ pub struct PlayerServer<I: std::iter::Iterator<Item=Result<Item, InterpreterErro keep_alive: bool, } -impl<I: std::iter::Iterator<Item=Result<Item, InterpreterError>>> PlayerServer<I> { +impl<I: std::iter::Iterator<Item = Result<Item, InterpreterError>>> PlayerServer<I> { pub fn new( player: Player<I>, ctrl: Receiver<ControlAction>, diff --git a/player/src/uri.rs b/player/src/uri.rs index 5b2f43f..f49da99 100644 --- a/player/src/uri.rs +++ b/player/src/uri.rs @@ -16,14 +16,14 @@ impl<'a> Uri<&'a str> { Some(end) => { // proper URI if let Some(query_start) = self.0.find('?') { - self.0.get(end+2..query_start).unwrap() + self.0.get(end + 2..query_start).unwrap() } else if let Some(frag_start) = self.0.find('#') { - self.0.get(end+2..frag_start).unwrap() + self.0.get(end + 2..frag_start).unwrap() } else { - self.0.get(end+2..).unwrap() + self.0.get(end + 2..).unwrap() } - }, - None => self.0 + } + None => self.0, } } diff --git a/src/cli.rs b/src/cli.rs index fd5a701..3a8227e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -34,7 +34,9 @@ pub fn parse() -> CliArgs { pub fn validate(args: &CliArgs) -> Result<(), String> { if let Some(mpd_addr) = &args.mpd { - let _: std::net::SocketAddr = mpd_addr.parse().map_err(|e| format!("Unrecognized MPS address `{}`: {}", mpd_addr, e))?; + let _: std::net::SocketAddr = mpd_addr + .parse() + .map_err(|e| format!("Unrecognized MPS address `{}`: {}", mpd_addr, e))?; } Ok(()) } diff --git a/src/main.rs b/src/main.rs index 86f387a..3c30bd2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -81,7 +81,12 @@ fn main() { // build playback controller let script_file2 = script_file.clone(); let volume = args.volume; - let mpd = match args.mpd.clone().map(|a| muss_player::mpd_connection(a.parse().unwrap())).transpose() { + let mpd = match args + .mpd + .clone() + .map(|a| muss_player::mpd_connection(a.parse().unwrap())) + .transpose() + { Ok(mpd) => mpd, Err(e) => panic!("Abort: Cannot connect to MPD: {}", e), }; diff --git a/src/repl.rs b/src/repl.rs index 9d6c87c..bce4236 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -1,27 +1,25 @@ //! Read, Execute, Print Loop functionality #![allow(clippy::single_match)] -use std::sync::{RwLock}; -use std::sync::mpsc::{self, Receiver}; use std::io::{self, Write}; +use std::sync::mpsc::{self, Receiver}; +use std::sync::RwLock; use lazy_static::lazy_static; use console::{Key, Term}; -use muss_interpreter::{Interpreter, Debugger, Item, InterpreterEvent, InterpreterError}; use muss_interpreter::lang::TypePrimitive; +use muss_interpreter::{Debugger, Interpreter, InterpreterError, InterpreterEvent, Item}; use muss_player::{Controller, Player}; use super::channel_io::{channel_io, ChannelWriter}; use super::cli::CliArgs; lazy_static! { - static ref DEBUG_STATE: RwLock<DebugState> = RwLock::new( - DebugState { - debug_flag: DebugFlag::Normal, - verbose: false, - } - ); + static ref DEBUG_STATE: RwLock<DebugState> = RwLock::new(DebugState { + debug_flag: DebugFlag::Normal, + verbose: false, + }); } const TERMINAL_WRITE_ERROR: &str = "Failed to write to terminal output"; @@ -55,7 +53,7 @@ struct DebugState { enum DebugFlag { Skip, List, - Normal + Normal, } impl ReplState { @@ -80,59 +78,79 @@ impl ReplState { } } -fn interpreter_event_callback<T: muss_interpreter::tokens::TokenReader>(_interpreter: &mut Interpreter<'_, T>, event: InterpreterEvent) -> Result<(), InterpreterError> { +fn interpreter_event_callback<T: muss_interpreter::tokens::TokenReader>( + _interpreter: &mut Interpreter<'_, T>, + event: InterpreterEvent, +) -> Result<(), InterpreterError> { match event { InterpreterEvent::StatementComplete => { if let Ok(mut d_state) = DEBUG_STATE.write() { d_state.debug_flag = DebugFlag::Normal; } - }, - _ => {}, + } + _ => {} } Ok(()) } #[inline] fn item_prompt(terminal: &mut Term, args: &CliArgs) { - write!(terminal, "*I{}", args.prompt) - .expect(TERMINAL_WRITE_ERROR); + write!(terminal, "*I{}", args.prompt).expect(TERMINAL_WRITE_ERROR); } fn pretty_print_item(item: &Item, terminal: &mut Term, args: &CliArgs, verbose: bool) { item_prompt(terminal, args); if verbose { - writeln!(terminal, "--\\/-- `{}` --\\/--", - item.field("title").unwrap_or(&TypePrimitive::Empty).as_str() - ).expect(TERMINAL_WRITE_ERROR); + writeln!( + terminal, + "--\\/-- `{}` --\\/--", + item.field("title") + .unwrap_or(&TypePrimitive::Empty) + .as_str() + ) + .expect(TERMINAL_WRITE_ERROR); let mut fields: Vec<&_> = item.iter().collect(); fields.sort(); for field in fields { if field != "title" { - writeln!(terminal, " {}: `{}`", + writeln!( + terminal, + " {}: `{}`", field, item.field(field).unwrap_or(&TypePrimitive::Empty).as_str() - ).expect(TERMINAL_WRITE_ERROR); + ) + .expect(TERMINAL_WRITE_ERROR); } } } else { - writeln!(terminal, "`{}` by `{}`", - item.field("title").unwrap_or(&TypePrimitive::Empty).as_str(), - item.field("artist").unwrap_or(&TypePrimitive::Empty).as_str(), - ).expect(TERMINAL_WRITE_ERROR); + writeln!( + terminal, + "`{}` by `{}`", + item.field("title") + .unwrap_or(&TypePrimitive::Empty) + .as_str(), + item.field("artist") + .unwrap_or(&TypePrimitive::Empty) + .as_str(), + ) + .expect(TERMINAL_WRITE_ERROR); } //writeln!(terminal, "I{}----", args.prompt).expect(TERMINAL_WRITE_ERROR); } fn handle_list_rx(state: &mut ReplState, args: &CliArgs) { //let items = state.list_rx.try_iter().collect::<Vec<_>>(); - let d_state = DEBUG_STATE.read().expect("Failed to get read lock for debug state info").clone(); + let d_state = DEBUG_STATE + .read() + .expect("Failed to get read lock for debug state info") + .clone(); for item in state.list_rx.try_iter() { match item { Ok(item) => pretty_print_item(&item, &mut state.terminal, args, d_state.verbose), Err(e) => error_prompt( - muss_player::PlayerError::Playback( - muss_player::PlaybackError::from_err(e) - ), args), + muss_player::PlayerError::Playback(muss_player::PlaybackError::from_err(e)), + args, + ), } } let flag = d_state.debug_flag; @@ -140,11 +158,13 @@ fn handle_list_rx(state: &mut ReplState, args: &CliArgs) { DebugFlag::List => { while let Ok(item) = state.list_rx.recv() { match item { - Ok(item) => pretty_print_item(&item, &mut state.terminal, args, d_state.verbose), + Ok(item) => { + pretty_print_item(&item, &mut state.terminal, args, d_state.verbose) + } Err(e) => error_prompt( - muss_player::PlayerError::Playback( - muss_player::PlaybackError::from_err(e) - ), args), + muss_player::PlayerError::Playback(muss_player::PlaybackError::from_err(e)), + args, + ), } // stop listing if no longer in list mode let flag = if let Ok(d_state) = DEBUG_STATE.read() { @@ -153,11 +173,11 @@ fn handle_list_rx(state: &mut ReplState, args: &CliArgs) { DebugFlag::Normal }; match flag { - DebugFlag::List => {}, + DebugFlag::List => {} _ => break, } } - }, + } _ => {} } } @@ -167,18 +187,26 @@ pub fn repl(args: CliArgs) { term.set_title("muss"); let (writer, reader) = channel_io(); let volume = args.volume; - let mpd = match args.mpd.clone().map(|a| muss_player::mpd_connection(a.parse().unwrap())).transpose() { + let mpd = match args + .mpd + .clone() + .map(|a| muss_player::mpd_connection(a.parse().unwrap())) + .transpose() + { Ok(mpd) => mpd, Err(e) => { - eprintln!("Cannot connect to MPD address `{}`: {}", args.mpd.unwrap(), e); + eprintln!( + "Cannot connect to MPD address `{}`: {}", + args.mpd.unwrap(), + e + ); return; } }; let (list_tx, list_rx) = mpsc::channel(); let mut state = ReplState::new(writer, term, list_rx); let player_builder = move || { - let runner = Interpreter::with_stream_and_callback(reader, - &interpreter_event_callback); + let runner = Interpreter::with_stream_and_callback(reader, &interpreter_event_callback); let debugger = Debugger::new(runner, move |interpretor, item| { let flag = if let Ok(d_state) = DEBUG_STATE.read() { d_state.debug_flag @@ -192,7 +220,7 @@ pub fn repl(args: CliArgs) { // NOTE: recursion occurs here } None - }, + } DebugFlag::List => { if let Some(x) = item { list_tx.send(x.map_err(|e| e.to_string())).unwrap_or(()); @@ -286,7 +314,11 @@ pub fn repl(args: CliArgs) { } } -fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut ReplState, mut execute: F) -> ! { +fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>( + args: &CliArgs, + state: &mut ReplState, + mut execute: F, +) -> ! { prompt(state, args); loop { match state @@ -296,13 +328,11 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep { Key::Char(read_c) => { if state.cursor_rightward_position == 0 { - write!(state.terminal, "{}", read_c) - .expect(TERMINAL_WRITE_ERROR); + write!(state.terminal, "{}", read_c).expect(TERMINAL_WRITE_ERROR); state.statement_buf.push(read_c); state.current_line.push(read_c); } else { - write!(state.terminal, "{}", read_c) - .expect(TERMINAL_WRITE_ERROR); + write!(state.terminal, "{}", read_c).expect(TERMINAL_WRITE_ERROR); for i in state.current_line.len() - state.cursor_rightward_position ..state.current_line.len() { @@ -346,21 +376,22 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep } ';' => { if state.in_literal.is_none() { - state - .terminal - .write_line("") - .expect(TERMINAL_WRITE_ERROR); + state.terminal.write_line("").expect(TERMINAL_WRITE_ERROR); let statement = state.statement_buf.iter().collect::<String>(); let statement_result = statement.trim(); if !statement_result.starts_with('?') { state .writer - .write_all(state.statement_buf.iter().collect::<String>().as_bytes()) + .write_all( + state.statement_buf.iter().collect::<String>().as_bytes(), + ) .expect(INTERPRETER_WRITE_ERROR); execute(state, args); state.statement_buf.clear(); } - let last_line = state.current_line[0..state.current_line.len() - 1].iter().collect::<String>(); + let last_line = state.current_line[0..state.current_line.len() - 1] + .iter() + .collect::<String>(); state.current_line.clear(); if !last_line.is_empty() && ((!state.history.is_empty() @@ -415,8 +446,7 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep .terminal .move_cursor_left(1) .expect(TERMINAL_WRITE_ERROR); - write!(state.terminal, " ") - .expect(TERMINAL_WRITE_ERROR); + write!(state.terminal, " ").expect(TERMINAL_WRITE_ERROR); state .terminal .flush() @@ -433,9 +463,9 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep let removed_char = state .current_line .remove(state.current_line.len() - state.cursor_rightward_position - 1); - state.statement_buf.remove( - state.statement_buf.len() - state.cursor_rightward_position - 1, - ); + state + .statement_buf + .remove(state.statement_buf.len() - state.cursor_rightward_position - 1); // re-sync unclosed syntax tracking match removed_char { '"' | '`' => { @@ -484,9 +514,9 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep let removed_char = state .current_line .remove(state.current_line.len() - state.cursor_rightward_position); - state.statement_buf.remove( - state.statement_buf.len() - state.cursor_rightward_position, - ); + state + .statement_buf + .remove(state.statement_buf.len() - state.cursor_rightward_position); // re-sync unclosed syntax tracking match removed_char { '"' | '`' => { @@ -528,10 +558,7 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep } } Key::Enter => { - state - .terminal - .write_line("") - .expect(TERMINAL_WRITE_ERROR); + state.terminal.write_line("").expect(TERMINAL_WRITE_ERROR); let statement = state.statement_buf.iter().collect::<String>(); let statement_result = statement.trim(); if statement_result.starts_with('?') { @@ -578,10 +605,7 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep 1 => { state.selected_history = 0; state.line_number -= 1; - state - .terminal - .clear_line() - .expect(TERMINAL_WRITE_ERROR); + state.terminal.clear_line().expect(TERMINAL_WRITE_ERROR); prompt(state, args); // clear stale input buffer state.statement_buf.clear(); @@ -589,12 +613,12 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep state.in_literal = None; state.bracket_depth = 0; state.curly_depth = 0; - }, - 0 => {}, + } + 0 => {} _ => { state.selected_history -= 1; display_history_line(state, args); - }, + } } } Key::ArrowLeft => { @@ -624,8 +648,7 @@ fn read_loop<F: FnMut(&mut ReplState, &CliArgs)>(args: &CliArgs, state: &mut Rep #[inline(always)] fn prompt(state: &mut ReplState, args: &CliArgs) { - write!(state.terminal, "{: >2}{}", state.line_number, args.prompt) - .expect(TERMINAL_WRITE_ERROR); + write!(state.terminal, "{: >2}{}", state.line_number, args.prompt).expect(TERMINAL_WRITE_ERROR); state.line_number += 1; state .terminal @@ -637,10 +660,7 @@ fn prompt(state: &mut ReplState, args: &CliArgs) { fn display_history_line(state: &mut ReplState, args: &CliArgs) { // get historical line state.line_number -= 1; - state - .terminal - .clear_line() - .expect(TERMINAL_WRITE_ERROR); + state.terminal.clear_line().expect(TERMINAL_WRITE_ERROR); prompt(state, args); let new_statement = state.history[state.history.len() - state.selected_history].trim(); state @@ -665,42 +685,62 @@ fn error_prompt(error: muss_player::PlayerError, args: &CliArgs) { fn repl_commands(command_str: &str, state: &mut ReplState, _args: &CliArgs) { let words: Vec<&str> = command_str.split(' ').map(|s| s.trim()).collect(); match words[0] { - "?help" => writeln!(state.terminal, "{}", super::help::HELP_STRING).expect(TERMINAL_WRITE_ERROR), - "?function" | "?functions" => writeln!(state.terminal, "{}", super::help::FUNCTIONS).expect(TERMINAL_WRITE_ERROR), - "?filter" | "?filters" => writeln!(state.terminal, "{}", super::help::FILTERS).expect(TERMINAL_WRITE_ERROR), - "?sort" | "?sorter" | "?sorters" => writeln!(state.terminal, "{}", super::help::SORTERS).expect(TERMINAL_WRITE_ERROR), - "?proc" | "?procedure" | "?procedures" => writeln!(state.terminal, "{}", super::help::PROCEDURES).expect(TERMINAL_WRITE_ERROR), + "?help" => { + writeln!(state.terminal, "{}", super::help::HELP_STRING).expect(TERMINAL_WRITE_ERROR) + } + "?function" | "?functions" => { + writeln!(state.terminal, "{}", super::help::FUNCTIONS).expect(TERMINAL_WRITE_ERROR) + } + "?filter" | "?filters" => { + writeln!(state.terminal, "{}", super::help::FILTERS).expect(TERMINAL_WRITE_ERROR) + } + "?sort" | "?sorter" | "?sorters" => { + writeln!(state.terminal, "{}", super::help::SORTERS).expect(TERMINAL_WRITE_ERROR) + } + "?proc" | "?procedure" | "?procedures" => { + writeln!(state.terminal, "{}", super::help::PROCEDURES).expect(TERMINAL_WRITE_ERROR) + } "?list" => { { - let mut debug_state = DEBUG_STATE.write().expect("Failed to get write lock for debug state"); + let mut debug_state = DEBUG_STATE + .write() + .expect("Failed to get write lock for debug state"); debug_state.debug_flag = DebugFlag::List; } writeln!(state.terminal, "Listing upcoming items").expect(TERMINAL_WRITE_ERROR); - - }, + } "?skip" => { { - let mut debug_state = DEBUG_STATE.write().expect("Failed to get write lock for debug state"); + let mut debug_state = DEBUG_STATE + .write() + .expect("Failed to get write lock for debug state"); debug_state.debug_flag = DebugFlag::Skip; } writeln!(state.terminal, "Skipping upcoming items").expect(TERMINAL_WRITE_ERROR); - }, + } "?normal" => { { - let mut debug_state = DEBUG_STATE.write().expect("Failed to get write lock for debug state"); + let mut debug_state = DEBUG_STATE + .write() + .expect("Failed to get write lock for debug state"); debug_state.debug_flag = DebugFlag::Normal; } writeln!(state.terminal, "Resuming normal operation").expect(TERMINAL_WRITE_ERROR); - }, + } "?verbose" => { let verbose = { - let mut debug_state = DEBUG_STATE.write().expect("Failed to get write lock for debug state"); + let mut debug_state = DEBUG_STATE + .write() + .expect("Failed to get write lock for debug state"); debug_state.verbose = !debug_state.verbose; debug_state.verbose }; - writeln!(state.terminal, "Verbosed toggled to {}", verbose).expect(TERMINAL_WRITE_ERROR); - }, - "?commands" => writeln!(state.terminal, "{}", super::help::REPL_COMMANDS).expect(TERMINAL_WRITE_ERROR), + writeln!(state.terminal, "Verbosed toggled to {}", verbose) + .expect(TERMINAL_WRITE_ERROR); + } + "?commands" => { + writeln!(state.terminal, "{}", super::help::REPL_COMMANDS).expect(TERMINAL_WRITE_ERROR) + } _ => writeln!(state.terminal, "Unknown command, try ?help").expect(TERMINAL_WRITE_ERROR), } }