diff --git a/Cargo.lock b/Cargo.lock index ae83303..fd715a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,17 +1229,17 @@ dependencies = [ ] [[package]] -name = "mps" +name = "muss" version = "0.8.0" dependencies = [ "clap 3.2.8", "console", - "mps-interpreter", - "mps-player", + "muss-interpreter", + "muss-player", ] [[package]] -name = "mps-interpreter" +name = "muss-interpreter" version = "0.8.0" dependencies = [ "bliss-audio-symphonia", @@ -1255,23 +1255,23 @@ dependencies = [ ] [[package]] -name = "mps-m3u8" +name = "muss-m3u8" version = "0.8.0" dependencies = [ "clap 3.2.8", "m3u8-rs", - "mps-interpreter", + "muss-interpreter", ] [[package]] -name = "mps-player" +name = "muss-player" version = "0.8.0" dependencies = [ "fluent-uri", "m3u8-rs", "mpd", "mpris-player", - "mps-interpreter", + "muss-interpreter", "rodio", ] diff --git a/Cargo.toml b/Cargo.toml index f45254c..260800e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "mps" +name = "muss" version = "0.8.0" edition = "2021" authors = ["NGnius (Graham) "] -description = "Music Playlist Script language (MPS)" +description = "Music Set Script language (MuSS)" license = "LGPL-2.1-only OR GPL-3.0-only" repository = "https://github.com/NGnius/mps" keywords = ["audio", "playlist", "scripting", "language"] @@ -19,17 +19,17 @@ members = [ [dependencies] # local -mps-interpreter = { version = "0.8.0", path = "./interpreter" } +muss-interpreter = { version = "0.8.0", path = "./interpreter" } # external clap = { version = "3.0", features = ["derive"] } console = { version = "0.15" } [target.'cfg(not(target_os = "linux"))'.dependencies] -mps-player = { version = "0.8.0", path = "./player", default-features = false } +muss-player = { version = "0.8.0", path = "./player", default-features = false } [target.'cfg(target_os = "linux")'.dependencies] # TODO fix need to specify OS-specific dependency of mps-player -mps-player = { version = "0.8.0", path = "./player", features = ["mpris-player", "mpd"] } +muss-player = { version = "0.8.0", path = "./player", features = ["mpris-player", "mpd"] } [profile.release] debug = false diff --git a/README.md b/README.md index 217e21b..558e376 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# mps +# muss ![repl_demo](https://raw.githubusercontent.com/NGnius/mps/master/extras/demo.png) Sort, filter and analyse your music to create great playlists. -This project implements the interpreter (mps-interpreter), music player (mps-player), and CLI interface for MPS (root). +This project implements the interpreter (`./interpreter`), music player (`./player`), and CLI interface for Muss (`./`). The CLI interface includes a REPL for running scripts. -The REPL interactive mode also provides more details about using MPS through the `?help` command. +The REPL interactive mode also provides more details about using Muss through the `?help` command. ## Usage To access the REPL, simply run `cargo run`. You will need the [Rust toolchain installed](https://rustup.rs/). For a bit of extra performance, run `cargo run --release` instead. @@ -15,38 +15,38 @@ To access the REPL, simply run `cargo run`. You will need the [Rust toolchain in ### One-liners All songs by artist `` (in your library), sorted by similarity to a random first song by the artist. -```mps +```muss files().(artist? like "")~(shuffle)~(advanced bliss_next); ``` All songs with a `.flac` file extension (anywhere in their path -- not necessarily at the end). -```mps +```muss files().(filename? like ".flac"); ``` All songs by artist `` or ``, sorted by similarity to a random first song by either artist. -```mps +```muss files().(artist? like "" || artist? like "")~(shuffle)~(advanced bliss_next); ``` ### Bigger examples -For now, check out `./src/tests`, `./mps-player/tests`, and `./mps-interpreter/tests` for examples. +For now, check out `./src/tests`, `./player/tests`, and `./interpreter/tests` for examples. One day I'll add pretty REPL example pictures and some script files... // TODO ## FAQ -### Can I use MPS right now? -**Sure!** It's never complete, but MPS is completely useable right now. Hopefully most of the bugs have been ironed out as well :) +### Can I use Muss right now? +**Sure!** It's never complete, but Muss is completely useable right now. Hopefully most of the bugs have been ironed out as well :) ### Why write a new language? **I thought it would be fun**. I also wanted to be able to play my music without having to be at the whim of someone else's algorithm (and music), and playing just by album or artist was getting boring. Designing a language specifically for iteration seemed like a cool & novel way of doing it, too (though every approach is a novel approach for me). -### What is MPS? -**Music Playlist Script (MPS) is technically a query language for music files.** It uses an (auto-generated) SQLite3 database for SQL queries and can also directly query the filesystem. Queries can be modified by using filters, functions, and sorters built-in to MPS (see mps-interpreter's README.md). +### What is Muss? +**Music Set Script (MuSS) is a language for describing a playlist of music.** It uses an (auto-generated) SQLite3 database for SQL queries and can also directly query the filesystem. Queries can be modified by using filters, functions, and sorters built-in to Muss (see interpreter's README.md). -### Is MPS a scripting language? +### Is Muss a scripting language? **Yes**. It evolved from a simple query language into something that can do arbitrary calculations. Whether it's Turing-complete is still unproven, but it's powerful enough for what I want it to do. diff --git a/interpreter/Cargo.toml b/interpreter/Cargo.toml index abaaec1..1a04f60 100644 --- a/interpreter/Cargo.toml +++ b/interpreter/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mps-interpreter" +name = "muss-interpreter" version = "0.8.0" edition = "2021" license = "LGPL-2.1-only OR GPL-3.0-only" diff --git a/interpreter/README.md b/interpreter/README.md index 293f90d..9d26208 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -1,21 +1,21 @@ -# mps-interpreter +# muss-interpreter -All necessary components to interpret and run a MPS script. +All necessary components to interpret and run a Muss script. -MpsFaye is the new interpreter, which replaces the old MpsInterpretor and MpsRunner types. -MpsDebugger can be used to run scripts with a custom debug harness. -Since MPS is centered around iterators, script execution is also done by iterating. +Interpreter is the Muss script interpreter. +Debugger can be used to run scripts within a custom debug harness. +Since Muss is centered around iterators, script execution is also done by iterating. ```rust use std::io::Cursor; -use mps_interpreter::*; +use muss_interpreter::*; let cursor = Cursor::new( "files(folder=`~/Music/`, recursive=true)" // retrieve all files from Music folder ); -let interpreter = MpsFaye::with_stream(cursor); +let interpreter = Interpreter::with_stream(cursor); // warning: my library has ~3800 songs, so this outputs too much information to be useful. for result in interpreter { @@ -28,15 +28,15 @@ for result in interpreter { ## Standard Vocabulary By default, the standard vocabulary is used to parse the stream when iterating the interpreter. -The standard vocabulary defines the valid statement syntax for MPS and parses syntax into special Rust Iterators which can be used to execute the statement. -To declare your own vocabulary, use MpsRunner::with_settings to provide a MpsInterpretor with a custom vocabulary (I'm not sure why you would, but I'm not going to stop you). +The standard vocabulary defines the valid statement syntax for Muss and parses syntax into special Rust Iterators which can be used to execute the statement. +To declare your own vocabulary, use Interpretor::with or Interpreter::with_vocab with a custom vocabulary (I'm not sure why you would, but I'm not going to stop you). ### Oddities -The MPS standard syntax does a few things that most other languages don't, because I wanted it to. +The Muss standard syntax does a few things that most other languages don't, because I wanted it to. \` can be used in place of " -- To make it easier to write SQL, string literals may be surrounded by backticks instead of quotation marks. -; -- The REPL will automatically place semicolons when Enter is pressed and it's not inside of brackets or a literal. MPS requires semicolons at the end of every statement, though, so MPS files must use semicolons. +; -- The REPL will automatically place semicolons when Enter is pressed and it's not inside of brackets or a literal. Muss requires semicolons at the end of every statement, though, so Muss files must use semicolons. ### Filters Operations to reduce the items in an iterable: `iterable.(filter);`. @@ -47,6 +47,8 @@ E.g. `files(folder="~/Music/", recursive=true).(title == "Romantic Traffic");` i #### field like something +#### field unlike something + #### field matches some_regex #### field != something @@ -59,7 +61,7 @@ E.g. `files(folder="~/Music/", recursive=true).(title == "Romantic Traffic");` i #### field < something -- e.g. `iterable.(title == "Romantic Traffic");` -Compare all items, keeping only those that match the condition. Valid field names are those of the MpsMusicItem (title, artist, album, genre, track, etc.), though this will change when proper object support is added. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). +Compare all items, keeping only those that match the condition. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). #### start..end -- e.g. `iterable.(0..42);` @@ -109,7 +111,7 @@ Initialize the SQLite database connection using the provided parameters. This mu #### sql("SQL query here"); -Perform a raw SQLite query on the database which MPS auto-generates. An iterator of the results is returned. +Perform a raw SQLite query on the database which Muss auto-generates. An iterator of the results is returned. #### song("something"); @@ -168,7 +170,7 @@ Operations to sort the items in an iterable: `iterable~(sorter)` OR `iterable.so #### field -- e.g. `iterable~(filename);` -Sort by a MpsItem field. Valid field names change depending on what information is available when the MpsItem is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. +Sort by a Item field. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. #### shuffle #### random shuffle -- e.g. `iterable~(shuffle);` @@ -201,7 +203,7 @@ Assign something to the variable. The variable must have already been declared. The empty or null constant. #### if condition { something } else { something_else } -- e.g. -```mps +```muss if item.title == `Romantic Traffic` { } else { diff --git a/interpreter/src/lib.rs b/interpreter/src/lib.rs index cb4c058..29afa14 100644 --- a/interpreter/src/lib.rs +++ b/interpreter/src/lib.rs @@ -1,19 +1,19 @@ -//! All necessary components to interpret and run a MPS script. +//! All necessary components to interpret and run a Muss script. //! -//! MpsFaye is the new interpreter, which replaces the old MpsInterpretor and MpsRunner types. -//! MpsDebugger can be used to run scripts with a custom debug harness. -//! Since MPS is centered around iterators, script execution is also done by iterating. +//! Interpreter is the Muss script interpreter. +//! Debugger can be used to run scripts within a custom debug harness. +//! Since Muss is centered around iterators, script execution is also done by iterating. //! //! //! ``` //! use std::io::Cursor; -//! use mps_interpreter::*; +//! use muss_interpreter::*; //! //! let cursor = Cursor::new( //! "files(folder=`~/Music/`, recursive=true)" // retrieve all files from Music folder //! ); //! -//! let interpreter = MpsFaye::with_stream(cursor); +//! let interpreter = Interpreter::with_stream(cursor); //! //! // warning: my library has ~3800 songs, so this outputs too much information to be useful. //! for result in interpreter { @@ -26,15 +26,15 @@ //! //! # Standard Vocabulary //! By default, the standard vocabulary is used to parse the stream when iterating the interpreter. -//! The standard vocabulary defines the valid statement syntax for MPS and parses syntax into special Rust Iterators which can be used to execute the statement. -//! To declare your own vocabulary, use MpsRunner::with_settings to provide a MpsInterpretor with a custom vocabulary (I'm not sure why you would, but I'm not going to stop you). +//! The standard vocabulary defines the valid statement syntax for Muss and parses syntax into special Rust Iterators which can be used to execute the statement. +//! To declare your own vocabulary, use Interpretor::with or Interpreter::with_vocab with a custom vocabulary (I'm not sure why you would, but I'm not going to stop you). //! //! ## Oddities -//! The MPS standard syntax does a few things that most other languages don't, because I wanted it to. +//! The Muss standard syntax does a few things that most other languages don't, because I wanted it to. //! //! \` can be used in place of " -- To make it easier to write SQL, string literals may be surrounded by backticks instead of quotation marks. //! -//! ; -- The REPL will automatically place semicolons when Enter is pressed and it's not inside of brackets or a literal. MPS requires semicolons at the end of every statement, though, so MPS files must use semicolons. +//! ; -- The REPL will automatically place semicolons when Enter is pressed and it's not inside of brackets or a literal. Muss requires semicolons at the end of every statement, though, so Muss files must use semicolons. //! //! ## Filters //! Operations to reduce the items in an iterable: `iterable.(filter);`. @@ -59,7 +59,7 @@ //! //! ### field < something -- e.g. `iterable.(title == "Romantic Traffic");` //! -//! Compare all items, keeping only those that match the condition. Valid field names are those of the MpsMusicItem (title, artist, album, genre, track, etc.), though this will change when proper object support is added. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). +//! Compare all items, keeping only those that match the condition. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). //! //! //! ### start..end -- e.g. `iterable.(0..42);` @@ -109,7 +109,7 @@ //! //! ### sql("SQL query here"); //! -//! Perform a raw SQLite query on the database which MPS auto-generates. An iterator of the results is returned. +//! Perform a raw SQLite query on the database which Muss auto-generates. An iterator of the results is returned. //! //! ### song("something"); //! @@ -168,7 +168,7 @@ //! //! ### field -- e.g. `iterable~(filename);` //! -//! Sort by a MpsItem field. Valid field names change depending on what information is available when the MpsItem is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. +//! Sort by a Item field. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. //! //! ### shuffle //! ### random shuffle -- e.g. `iterable~(shuffle);` @@ -201,7 +201,7 @@ //! The empty or null constant. //! //! ### if condition { something } else { something_else } -- e.g. -//! ```mps +//! ```muss //! if item.title == `Romantic Traffic` { //! //! } else { diff --git a/m3u8/Cargo.toml b/m3u8/Cargo.toml index e7d3f53..a5bdfa1 100644 --- a/m3u8/Cargo.toml +++ b/m3u8/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mps-m3u8" +name = "muss-m3u8" version = "0.8.0" edition = "2021" authors = ["NGnius "] @@ -13,7 +13,7 @@ readme = "README.md" [dependencies] # local -mps-interpreter = { version = "0.8.0", path = "../interpreter" } +muss-interpreter = { version = "0.8.0", path = "../interpreter" } # external clap = { version = "3.0", features = ["derive"] } m3u8-rs = { version = "^3.0.0" } diff --git a/m3u8/src/main.rs b/m3u8/src/main.rs index 1a534ff..e1da003 100644 --- a/m3u8/src/main.rs +++ b/m3u8/src/main.rs @@ -1,6 +1,6 @@ -//! Minimal CLI tool to generate a m3u8 playlist from a MPS file. +//! Minimal CLI tool to generate a m3u8 playlist from a Muss script. //! This does not support playback, so it can run on any platform with a filesystem. -//! Use `mps-m3u8 --help` for usage instructions. +//! Use `muss-m3u8 --help` for usage instructions. //! mod cli; diff --git a/player/Cargo.toml b/player/Cargo.toml index f2664a1..28afc8b 100644 --- a/player/Cargo.toml +++ b/player/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "mps-player" +name = "muss-player" version = "0.8.0" edition = "2021" license = "LGPL-2.1-only OR GPL-3.0-only" @@ -12,7 +12,7 @@ fluent-uri = { version = "^0.1" } mpd = { version = "0.0.12", optional = true } # local -mps-interpreter = { path = "../interpreter", version = "0.8.0" } +muss-interpreter = { path = "../interpreter", version = "0.8.0" } [target.'cfg(target_os = "linux")'.dependencies] #dbus = { version = "^0.9" } diff --git a/player/README.md b/player/README.md index a6d18a7..e1500bb 100644 --- a/player/README.md +++ b/player/README.md @@ -1,8 +1,8 @@ -# mps-player +# muss-player -An MPS playback library with support for media controls (Linux & D-Bus only atm). +A Muss playback library with support for media controls (Linux & D-Bus only atm). This handles the output from interpreting a script. Music playback and m3u8 playlist generation are implemented in this part of the project. -License: LGPL-2.1-only OR GPL-2.0-or-later +License: LGPL-2.1-only OR GPL-3.0-only diff --git a/player/src/controller.rs b/player/src/controller.rs index 8788cdd..55caf5a 100644 --- a/player/src/controller.rs +++ b/player/src/controller.rs @@ -1,7 +1,7 @@ use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread::JoinHandle; -use mps_interpreter::tokens::TokenReader; +use muss_interpreter::tokens::TokenReader; use super::os_controls::SystemControlWrapper; use super::player_wrapper::{ControlAction, PlayerServer, PlayerAction}; diff --git a/player/src/lib.rs b/player/src/lib.rs index 6946741..e1da6bb 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -1,4 +1,4 @@ -//! An playback library with support for media controls (Linux & D-Bus only atm). +//! A Muss playback library with support for media controls (Linux & D-Bus only atm). //! This handles the output from interpreting a script. //! Music playback and m3u8 playlist generation are implemented in this part of the project. //! diff --git a/player/src/os_controls.rs b/player/src/os_controls.rs index 46bdda0..096c957 100644 --- a/player/src/os_controls.rs +++ b/player/src/os_controls.rs @@ -7,7 +7,7 @@ use std::thread::JoinHandle; use mpris_player::{Metadata, MprisPlayer, PlaybackStatus}; #[cfg(all(target_os = "linux", feature = "os-controls", feature = "mpris-player"))] -use mps_interpreter::Item; +use muss_interpreter::Item; //use super::Controller; use super::player_wrapper::{ControlAction, PlaybackAction}; diff --git a/player/src/player.rs b/player/src/player.rs index ea76e3d..35cac39 100644 --- a/player/src/player.rs +++ b/player/src/player.rs @@ -10,7 +10,7 @@ use mpd::{Client, Song, error}; use super::uri::Uri; -use mps_interpreter::{tokens::TokenReader, Interpreter, Item}; +use muss_interpreter::{tokens::TokenReader, Interpreter, Item}; //use super::PlaybackError; use super::PlayerError; diff --git a/player/src/player_wrapper.rs b/player/src/player_wrapper.rs index 7b6fedf..215273d 100644 --- a/player/src/player_wrapper.rs +++ b/player/src/player_wrapper.rs @@ -1,8 +1,8 @@ use std::sync::mpsc::{Receiver, Sender}; use std::{thread, thread::JoinHandle}; -use mps_interpreter::tokens::TokenReader; -use mps_interpreter::Item; +use muss_interpreter::tokens::TokenReader; +use muss_interpreter::Item; use super::Player; use super::PlayerError; diff --git a/player/src/utility.rs b/player/src/utility.rs index 009e7f6..fdd11a0 100644 --- a/player/src/utility.rs +++ b/player/src/utility.rs @@ -2,7 +2,7 @@ use std::path::Path; use std::io; use std::fs; -use mps_interpreter::{Intrepreter, tokens::TokenReader}; +use muss_interpreter::{Intrepreter, tokens::TokenReader}; use super::{Player, PlaybackError}; diff --git a/src/help.rs b/src/help.rs index d06b739..d217945 100644 --- a/src/help.rs +++ b/src/help.rs @@ -1,4 +1,4 @@ -/// Standard help string containing usage information for MPS. +/// Standard help string containing usage information for Muss. pub const HELP_STRING: &str = "This language is all about iteration. Almost everything is an iterator or operates on iterators. By default, any operation which is not an assignment will cause the script runner to handle (play/save) the items which that statement contains. @@ -13,7 +13,7 @@ These always return an iterable which can be manipulated. Initialize the SQLite database connection using the provided parameters. This must be performed before any other database operation (otherwise the database will already be connected with default settings). Returns an empty iterable. sql(`SQL query here`) - Perform a raw SQLite query on the database which MPS auto-generates. An iterator of the results is returned. + Perform a raw SQLite query on the database which Muss auto-generates. An iterator of the results is returned. song(`something`) Retrieve all songs in the database with a title like something. @@ -68,7 +68,7 @@ Operations to reduce the items in an iterable: iterable.(filter) field > something field <= something field < something -- e.g. iterable.(title == `Romantic Traffic`) - Compare all items, keeping only those that match the condition. Valid field names change depending on what information is available when the MpsItem is populated, but usually title, artist, album, genre, track, filename are valid fields. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). + Compare all items, keeping only those that match the condition. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Optionally, a ? or ! can be added to the end of the field name to skip items whose field is missing/incomparable, or keep all items whose field is missing/incomparable (respectively). start..end -- e.g. iterable.(0..42) Keep only the items that are at the start index up to the end index. Start and/or end may be omitted to start/stop at the iterable's existing start/end (respectively). This stops once the end condition is met, leaving the rest of the iterator unconsumed. @@ -100,17 +100,17 @@ pub const SORTERS: &str = Operations to sort the items in an iterable: iterable~(sorter) OR iterable.sort(sorter) field -- e.g. iterable~(filename) - Sort by a MpsItem field. Valid field names change depending on what information is available when the MpsItem is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. + Sort by a Item field. Valid field names change depending on what information is available when the Item is populated, but usually title, artist, album, genre, track, filename are valid fields. Items with a missing/incomparable fields will be sorted to the end. shuffle random shuffle -- e.g. iterable~(shuffle) Shuffle the songs in the iterator. This is random for up to 2^16 items, and then the randomness degrades (but at that point you won't notice). advanced bliss_first -- e.g. iterable~(advanced bliss_first) - Sort by the distance (similarity) from the first song in the iterator. Songs which are more similar (lower distance) to the first song in the iterator will be placed closer to the first song, while less similar songs will be sorted to the end. This uses the bliss music analyser, which is a very slow operation and can cause music playback interruptions for large iterators. Requires `advanced` mps-interpreter feature. + Sort by the distance (similarity) from the first song in the iterator. Songs which are more similar (lower distance) to the first song in the iterator will be placed closer to the first song, while less similar songs will be sorted to the end. This uses the bliss music analyser, which is a very slow operation and can cause music playback interruptions for large iterators. Requires `advanced` interpreter feature. advanced bliss_next -- e.g. iterable~(advanced bliss_next) - Sort by the distance (similarity) between the last played song in the iterator. Similar to bliss_first. Songs which are more similar (lower distance) to the first song in the iterator will be placed closer to the first song, while less similar songs will be sorted to the end. This uses the bliss music analyser, which is a very slow operation and can cause music playback interruptions for large iterators. Requires `advanced` mps-interpreter feature."; + Sort by the distance (similarity) between the last played song in the iterator. Similar to bliss_first. Songs which are more similar (lower distance) to the first song in the iterator will be placed closer to the first song, while less similar songs will be sorted to the end. This uses the bliss music analyser, which is a very slow operation and can cause music playback interruptions for large iterators. Requires `advanced` interpreter feature."; pub const PROCEDURES: &str = "PROCEDURES (?procedures) diff --git a/src/main.rs b/src/main.rs index d7122ea..04d8e3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ //! Sort, filter and analyse your music to create great playlists. -//! This project implements the interpreter (mps-interpreter), music player (mps-player), and CLI interface for MPS (root). +//! This project implements the interpreter (`./interpreter`), music player (`./player`), and CLI interface for Muss (`./`). //! The CLI interface includes a REPL for running scripts. -//! The REPL interactive mode also provides more details about using MPS through the `?help` command. +//! The REPL interactive mode also provides more details about using Muss through the `?help` command. //! //! # Usage //! To access the REPL, simply run `cargo run`. You will need the [Rust toolchain installed](https://rustup.rs/). For a bit of extra performance, run `cargo run --release` instead. @@ -11,38 +11,38 @@ //! ## One-liners //! //! All songs by artist `` (in your library), sorted by similarity to a random first song by the artist. -//! ```mps +//! ```muss //! files().(artist? like "")~(shuffle)~(advanced bliss_next); //! ``` //! //! All songs with a `.flac` file extension (anywhere in their path -- not necessarily at the end). -//! ```mps +//! ```muss //! files().(filename? like ".flac"); //! ``` //! //! All songs by artist `` or ``, sorted by similarity to a random first song by either artist. -//! ```mps +//! ```muss //! files().(artist? like "" || artist? like "")~(shuffle)~(advanced bliss_next); //! ``` //! //! ## Bigger examples //! -//! For now, check out `./src/tests`, `./mps-player/tests`, and `./mps-interpreter/tests` for examples. +//! For now, check out `./src/tests`, `./player/tests`, and `./interpreter/tests` for examples. //! One day I'll add pretty REPL example pictures and some script files... //! // TODO //! //! # FAQ //! -//! ## Can I use MPS right now? -//! **Sure!** It's never complete, but MPS is completely useable right now. Hopefully most of the bugs have been ironed out as well :) +//! ## Can I use Muss right now? +//! **Sure!** It's never complete, but Muss is completely useable right now. Hopefully most of the bugs have been ironed out as well :) //! //! ## Why write a new language? //! **I thought it would be fun**. I also wanted to be able to play my music without having to be at the whim of someone else's algorithm (and music), and playing just by album or artist was getting boring. Designing a language specifically for iteration seemed like a cool & novel way of doing it, too (though every approach is a novel approach for me). //! -//! ## What is MPS? -//! **Music Playlist Script (MPS) is technically a query language for music files.** It uses an (auto-generated) SQLite3 database for SQL queries and can also directly query the filesystem. Queries can be modified by using filters, functions, and sorters built-in to MPS (see mps-interpreter's README.md). +//! ## What is Muss? +//! **Music Set Script (MuSS) is a language for describing a playlist of music.** It uses an (auto-generated) SQLite3 database for SQL queries and can also directly query the filesystem. Queries can be modified by using filters, functions, and sorters built-in to Muss (see interpreter's README.md). //! -//! ## Is MPS a scripting language? +//! ## Is Muss a scripting language? //! **Yes**. It evolved from a simple query language into something that can do arbitrary calculations. Whether it's Turing-complete is still unproven, but it's powerful enough for what I want it to do. //! @@ -54,8 +54,8 @@ mod repl; use std::io; use std::path::PathBuf; -use mps_interpreter::Interpreter; -use mps_player::{Controller, Player, PlayerError}; +use muss_interpreter::Interpreter; +use muss_player::{Controller, Player, PlayerError}; #[allow(dead_code)] fn play_cursor() -> Result<(), PlayerError> { @@ -81,7 +81,7 @@ fn main() { // build playback controller let script_file2 = script_file.clone(); let volume = args.volume.clone(); - let mpd = match args.mpd.clone().map(|a| mps_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), }; @@ -125,7 +125,7 @@ fn main() { } } else { // start REPL - println!("Welcome to MPS interactive mode!"); + println!("Welcome to Muss interactive mode!"); println!("Run ?help for usage instructions."); //println!("End a statement with ; to execute it."); repl::repl(args) diff --git a/src/repl.rs b/src/repl.rs index 532e4de..711c04a 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -4,8 +4,8 @@ use std::io::{self, Write}; use console::{Key, Term}; -use mps_interpreter::Interpreter; -use mps_player::{Controller, Player}; +use muss_interpreter::Interpreter; +use muss_player::{Controller, Player}; use super::channel_io::{channel_io, ChannelWriter}; use super::cli::CliArgs; @@ -47,7 +47,7 @@ pub fn repl(args: CliArgs) { term.set_title("mps"); let (writer, reader) = channel_io(); let volume = args.volume.clone(); - let mpd = match args.mpd.clone().map(|a| mps_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); @@ -458,7 +458,7 @@ fn display_history_line(state: &mut ReplState, args: &CliArgs) { } #[inline(always)] -fn error_prompt(error: mps_player::PlayerError, args: &CliArgs) { +fn error_prompt(error: muss_player::PlayerError, args: &CliArgs) { eprintln!("E{}{}", args.prompt, error); }