mirror of
https://github.com/PaddiM8/kalker.git
synced 2025-01-19 03:38:13 +01:00
Replaced manual cli arg parsing with the seahorse crate
This commit is contained in:
parent
339d98e2c6
commit
b3720ed6dc
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -170,6 +170,7 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"regex",
|
"regex",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
|
"seahorse",
|
||||||
"winres",
|
"winres",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -315,6 +316,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "seahorse"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce7d9440e2865cce0db733bdc530591b37d37a2d32badace34a1fc9ba5686d58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.118"
|
version = "1.0.118"
|
||||||
|
@ -21,6 +21,7 @@ rustyline = "7.0.0"
|
|||||||
ansi_term = "0.12"
|
ansi_term = "0.12"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
seahorse = "1.1.1"
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
winres = "0.1"
|
winres = "0.1"
|
||||||
|
@ -2,6 +2,7 @@ mod output;
|
|||||||
mod repl;
|
mod repl;
|
||||||
|
|
||||||
use kalk::parser;
|
use kalk::parser;
|
||||||
|
use seahorse::{App, Context, Flag, FlagType};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@ -9,76 +10,72 @@ use std::io::Read;
|
|||||||
static DEFAULT_PRECISION: u32 = 53;
|
static DEFAULT_PRECISION: u32 = 53;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut parser_context = parser::Context::new().set_angle_unit(&get_angle_unit());
|
let args: Vec<String> = env::args().collect();
|
||||||
|
let app = App::new("kalk")
|
||||||
|
.author(env!("CARGO_PKG_AUTHORS"))
|
||||||
|
.version(env!("CARGO_PKG_VERSION"))
|
||||||
|
.usage("kalk [options] [input]")
|
||||||
|
.action(default_action)
|
||||||
|
.flag(
|
||||||
|
Flag::new("input-file", FlagType::String)
|
||||||
|
.description("Load a file with predefined variables and functions")
|
||||||
|
.alias("i"),
|
||||||
|
)
|
||||||
|
.flag(
|
||||||
|
Flag::new("precision", FlagType::Int)
|
||||||
|
.description("Specify number precision")
|
||||||
|
.alias("p"),
|
||||||
|
)
|
||||||
|
.flag(
|
||||||
|
Flag::new("angle-unit", FlagType::String)
|
||||||
|
.description("Unit used for angles, either rad or deg. This can also be specified using an environment variable with the name 'ANGLE_UNIT'.")
|
||||||
|
.alias("a"),
|
||||||
|
);
|
||||||
|
|
||||||
// Command line argument input, execute it and exit.
|
app.run(args);
|
||||||
let mut args = env::args().skip(1);
|
}
|
||||||
let mut expr_input: Option<String> = None;
|
|
||||||
let mut precision = DEFAULT_PRECISION;
|
|
||||||
loop {
|
|
||||||
// Get the next argument if possible, otherwise break the loop.
|
|
||||||
let arg = if let Some(arg) = args.next() {
|
|
||||||
arg
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
|
|
||||||
match arg.as_ref() {
|
fn default_action(context: &Context) {
|
||||||
"-h" | "--help" => {
|
let angle_unit = if let Ok(angle_unit) = context.string_flag("angle-unit") {
|
||||||
// The indentation... Will have to do something more scalable in the future.
|
match angle_unit.as_ref() {
|
||||||
println!(
|
"rad" | "deg" => angle_unit,
|
||||||
"
|
|
||||||
[kalk help]
|
|
||||||
|
|
||||||
kalk [OPTIONS] [INPUT]
|
|
||||||
-h, --help : show this
|
|
||||||
-i : load a file with predefined functions/variables
|
|
||||||
--precision : specify number precision
|
|
||||||
|
|
||||||
[Environment variables]
|
|
||||||
ANGLE_UNIT=(deg/rad) : Sets the default unit used for trigonometric functions.
|
|
||||||
"
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
"-i" => {
|
|
||||||
let file_name = &args.next().expect("Expected input file."); // The next argument will be the file name.
|
|
||||||
let mut file_content = String::new();
|
|
||||||
File::open(&file_name)
|
|
||||||
.expect("Couldn't find file.")
|
|
||||||
.read_to_string(&mut file_content)
|
|
||||||
.expect("Failed to read input file.");
|
|
||||||
|
|
||||||
// Parse the input file content, resulting in the symbol table being filled out.
|
|
||||||
// Output is not needed here.
|
|
||||||
parser::eval(&mut parser_context, &file_content, precision)
|
|
||||||
.expect("Failed to parse input file.");
|
|
||||||
}
|
|
||||||
"--precision" => {
|
|
||||||
precision = args
|
|
||||||
.next()
|
|
||||||
.expect("Expected precision input.")
|
|
||||||
.parse::<u32>()
|
|
||||||
.expect("Precision value could not be parsed.");
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
// Main argument. This is expected to be a maths expression.
|
output::print_err("Invalid angle unit. Expected 'rad' or 'deg'.");
|
||||||
// After the loop is finished, this will be parsed and outputted.
|
std::process::exit(1);
|
||||||
expr_input = Some(arg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
get_env_angle_unit()
|
||||||
|
};
|
||||||
|
let mut parser_context = parser::Context::new().set_angle_unit(&angle_unit);
|
||||||
|
let precision = context.int_flag("precision").unwrap_or(53isize) as u32;
|
||||||
|
|
||||||
|
if let Ok(input_file_path) = context.string_flag("input-file") {
|
||||||
|
load_input_file(&input_file_path, precision, &mut parser_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(input) = expr_input {
|
if context.args.len() == 0 {
|
||||||
// Direct output
|
|
||||||
output::eval(&mut parser_context, &input, precision);
|
|
||||||
} else {
|
|
||||||
// REPL
|
// REPL
|
||||||
repl::start(&mut parser_context, precision);
|
repl::start(&mut parser_context, precision);
|
||||||
|
} else {
|
||||||
|
// Direct output
|
||||||
|
output::eval(&mut parser_context, &context.args.join(" "), precision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_angle_unit() -> String {
|
fn load_input_file(file_name: &str, precision: u32, parser_context: &mut parser::Context) {
|
||||||
|
let mut file_content = String::new();
|
||||||
|
File::open(&file_name)
|
||||||
|
.expect("Couldn't find file.")
|
||||||
|
.read_to_string(&mut file_content)
|
||||||
|
.expect("Failed to read input file.");
|
||||||
|
|
||||||
|
// Parse the input file content, resulting in the symbol table being filled out.
|
||||||
|
// Output is not needed here.
|
||||||
|
parser::eval(parser_context, &file_content, precision).expect("Failed to parse input file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_env_angle_unit() -> String {
|
||||||
if let Ok(angle_unit_var) = env::var("ANGLE_UNIT") {
|
if let Ok(angle_unit_var) = env::var("ANGLE_UNIT") {
|
||||||
angle_unit_var
|
angle_unit_var
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user