use std::process::exit;
use structopt::StructOpt;
use textplots::{Chart, Plot, Shape};
#[derive(StructOpt)]
struct Opt {
#[structopt(name = "FORMULA")]
formula: String,
#[structopt(long, default_value = "-10.0")]
xmin: f32,
#[structopt(long, default_value = "10.0")]
xmax: f32,
#[structopt(long)]
ymin: Option<f32>,
#[structopt(long)]
ymax: Option<f32>,
#[structopt(short, long, default_value = "180")]
width: u32,
#[structopt(short, long, default_value = "60")]
height: u32,
}
fn main() {
let opt = Opt::from_args();
let res = opt
.formula
.parse()
.and_then(|expr: meval::Expr| expr.bind("x"));
let func = match res {
Ok(func) => func,
Err(err) => {
eprintln!("{}", err);
exit(1);
}
};
if (opt.ymax.is_none() && opt.ymin.is_some()) || (opt.ymax.is_some() && opt.ymin.is_none()) {
eprintln!("both ymin and ymax must be specified");
exit(2);
}
println!("y = {}", opt.formula);
let mut chart = if opt.ymin.is_none() {
Chart::new(opt.width, opt.height, opt.xmin, opt.xmax)
} else {
Chart::new_with_y_range(
opt.width,
opt.height,
opt.xmin,
opt.xmax,
opt.ymin.unwrap(),
opt.ymax.unwrap(),
)
};
chart
.lineplot(&Shape::Continuous(Box::new(|x| func(x.into()) as f32)))
.display();
}