list subcommand support
This commit is contained in:
parent
efceea0705
commit
e40f6f48a1
3 changed files with 146 additions and 13 deletions
37
src/cli.rs
37
src/cli.rs
|
@ -1,7 +1,10 @@
|
|||
use std::{fmt::Display, fs::read_to_string, io, str::FromStr};
|
||||
use std::{convert::Infallible, fmt::Display, fs::read_to_string, io, str::FromStr};
|
||||
|
||||
use amplify::{From, Wrapper};
|
||||
use clap::Parser;
|
||||
use strum::EnumString;
|
||||
|
||||
pub mod doc;
|
||||
|
||||
/// Cli entry point
|
||||
#[derive(Clone, Parser)]
|
||||
|
@ -9,9 +12,9 @@ use clap::Parser;
|
|||
pub enum BngCli {
|
||||
/// Play the song through default sink
|
||||
Play(PlayOpts),
|
||||
/// Export the song to a sound FileContents
|
||||
/// Export the song to a sound file
|
||||
Export(ExportOpts),
|
||||
/// List supported sound FileContents extensions and instrument / song available expressions
|
||||
/// List supported sound file extensions and instrument / song available expressions
|
||||
#[command(subcommand)]
|
||||
List(ListOpts),
|
||||
}
|
||||
|
@ -28,10 +31,10 @@ pub struct PlayOpts {
|
|||
#[derive(Clone, Parser)]
|
||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||
pub struct ExportOpts {
|
||||
/// Input FileContents (written song FileContents)
|
||||
/// Input file (written song file)
|
||||
#[arg(value_parser = FileContents::from_str)]
|
||||
input: FileContents,
|
||||
/// Output FileContents (sound FileContents)
|
||||
/// Output file (sound file)
|
||||
#[arg(value_parser = AudioFileName::from_str)]
|
||||
output: AudioFileName,
|
||||
}
|
||||
|
@ -40,17 +43,29 @@ pub struct ExportOpts {
|
|||
#[derive(Clone, Parser)]
|
||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||
pub enum ListOpts {
|
||||
/// List supported sound FileContents extensions to export songs
|
||||
#[command(subcommand)]
|
||||
/// List supported sound file extensions to export songs
|
||||
Extensions,
|
||||
/// List available math expressions for instrument definition
|
||||
#[command(subcommand)]
|
||||
Math,
|
||||
/// Show the math syntax used for instrument definition and slopes
|
||||
Math {
|
||||
/// Kind of syntax you want to list (functions, operators or literals)
|
||||
#[arg(value_parser = MathDocKind::from_str)]
|
||||
kind: Option<MathDocKind>,
|
||||
},
|
||||
/// List available score glyphs and their meaning
|
||||
#[command(subcommand)]
|
||||
Glyphs,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, EnumString)]
|
||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||
pub enum MathDocKind {
|
||||
#[strum(ascii_case_insensitive)]
|
||||
Functions,
|
||||
#[strum(ascii_case_insensitive)]
|
||||
Operators,
|
||||
#[strum(ascii_case_insensitive)]
|
||||
Literals,
|
||||
}
|
||||
|
||||
#[derive(Clone, Wrapper, From)]
|
||||
#[wrapper(Deref)]
|
||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||
|
|
98
src/cli/doc.rs
Normal file
98
src/cli/doc.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
pub mod math {
|
||||
pub const FUNCTIONS: &str = r#"* print(...strings and values...) -- Prints to stderr. Very useful to 'probe' an expression.
|
||||
Evaluates to the last value.
|
||||
Example: `print("x is", x, "and y is", y)`
|
||||
Example: `x + print("y:", y) + z == x+y+z`
|
||||
|
||||
* log(base=10, val) -- Logarithm with optional 'base' as first argument.
|
||||
If not provided, 'base' defaults to '10'.
|
||||
Example: `log(100) + log(e(), 100)`
|
||||
|
||||
* e() -- Euler's number (2.718281828459045)
|
||||
* pi() -- π (3.141592653589793)
|
||||
|
||||
* int(val)
|
||||
* ceil(val)
|
||||
* floor(val)
|
||||
* round(modulus=1, val) -- Round with optional 'modulus' as first argument.
|
||||
Example: `round(1.23456) == 1 && round(0.001, 1.23456) == 1.235`
|
||||
|
||||
* abs(val)
|
||||
* sign(val)
|
||||
|
||||
* min(val, ...) -- Example: `min(1, -2, 3, -4) == -4`
|
||||
* max(val, ...) -- Example: `max(1, -2, 3, -4) == 3`
|
||||
|
||||
* sin(radians) * asin(val)
|
||||
* cos(radians) * acos(val)
|
||||
* tan(radians) * atan(val)
|
||||
* sinh(val) * asinh(val)
|
||||
* cosh(val) * acosh(val)
|
||||
* tanh(val) * atanh(val)"#;
|
||||
pub const OPERATORS: &str = r#"Listed in order of precedence:
|
||||
|
||||
(Highest Precedence) ^ Exponentiation
|
||||
% Modulo
|
||||
/ Division
|
||||
* Multiplication
|
||||
- Subtraction
|
||||
+ Addition
|
||||
== != < <= >= > Comparisons (all have equal precedence)
|
||||
&& and Logical AND with short-circuit
|
||||
(Lowest Precedence) || or Logical OR with short-circuit"#;
|
||||
pub const LITERALS: &str = r#"Several numeric formats are supported:
|
||||
|
||||
Integers: 1, 2, 10, 100, 1001
|
||||
|
||||
Decimals: 1.0, 1.23456, 0.000001
|
||||
|
||||
Exponents: 1e3, 1E3, 1e-3, 1E-3, 1.2345e100
|
||||
|
||||
Suffix:
|
||||
1.23p = 0.00000000000123
|
||||
1.23n = 0.00000000123
|
||||
1.23µ, 1.23u = 0.00000123
|
||||
1.23m = 0.00123
|
||||
1.23K, 1.23k = 1230
|
||||
1.23M = 1230000
|
||||
1.23G = 1230000000
|
||||
1.23T = 1230000000000"#;
|
||||
}
|
||||
|
||||
pub mod glyphs {
|
||||
pub const ALL: &str = r#"rest: .
|
||||
pizz.: '°
|
||||
volume: +-
|
||||
length: /\
|
||||
octave: ><
|
||||
comment?: ;,
|
||||
start here: ':'
|
||||
slope: {{MODIFIER EXPR score}}
|
||||
note modifier prefix: n
|
||||
volume modifier prefix: v
|
||||
octave modifier prefix: o
|
||||
length modifier prefix: l
|
||||
tempo modifier prefix: t
|
||||
loop: ()
|
||||
loop with count: (COUNT score)
|
||||
tuple: []
|
||||
modifier: !
|
||||
volume modifier prefix: v
|
||||
octave modifier prefix: o
|
||||
length modifier prefix: l
|
||||
tempo modifier prefix: t
|
||||
|
||||
EXAMPLE
|
||||
aabc.
|
||||
'ab°A
|
||||
+d+d+d---
|
||||
/ff/f\\
|
||||
ab>c<ba
|
||||
;this is a comment (or lyrics whatever),
|
||||
C:CC
|
||||
(3deff)
|
||||
(deff)
|
||||
[ffe]
|
||||
{{l 1-cos((PI*x)/2),acced}}
|
||||
abbc!o5cc!v15feed!l4fedd!t60Gdd"#;
|
||||
}
|
24
src/main.rs
24
src/main.rs
|
@ -4,7 +4,7 @@ use anyhow::Error;
|
|||
use bng::{BngFile, Channel, Expression, Instrument};
|
||||
/// TODO: remove clap, use only a file or standard in
|
||||
use clap::Parser;
|
||||
use cli::{BngCli as Cli, PlayOpts};
|
||||
use cli::{doc, BngCli as Cli, ListOpts, MathDocKind, PlayOpts};
|
||||
use fasteval::Compiler;
|
||||
|
||||
mod bng;
|
||||
|
@ -24,7 +24,27 @@ fn main() -> Result<(), Error> {
|
|||
#[cfg(debug_assertions)]
|
||||
println!("{:#?}", bng_file);
|
||||
}
|
||||
_ => unimplemented!("can't do that yet"),
|
||||
Cli::List(l) => match l {
|
||||
ListOpts::Extensions => println!("you can't export songs yet"),
|
||||
ListOpts::Math { kind } => match kind {
|
||||
None => println!(
|
||||
"Functions :\n{}\n\nOperators :\n{}\n\nLiterals :\n{}",
|
||||
doc::math::FUNCTIONS,
|
||||
doc::math::OPERATORS,
|
||||
doc::math::LITERALS
|
||||
),
|
||||
Some(m) => println!(
|
||||
"{}",
|
||||
match m {
|
||||
MathDocKind::Functions => doc::math::FUNCTIONS,
|
||||
MathDocKind::Operators => doc::math::OPERATORS,
|
||||
MathDocKind::Literals => doc::math::LITERALS,
|
||||
}
|
||||
),
|
||||
},
|
||||
ListOpts::Glyphs => println!("{}", doc::glyphs::ALL),
|
||||
},
|
||||
Cli::Export(_) => unimplemented!("can't do that yet"),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue