Make a calc command (#1280)

This commit is contained in:
Shaurya Shubham 2020-01-29 19:04:36 +05:30 committed by GitHub
parent ac5ad45783
commit dc3370b103
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 128 additions and 0 deletions

17
Cargo.lock generated
View file

@ -1927,6 +1927,16 @@ dependencies = [
"rustc_version",
]
[[package]]
name = "meval"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79496a5651c8d57cd033c5add8ca7ee4e3d5f7587a4777484640d9cb60392d9"
dependencies = [
"fnv",
"nom 1.2.4",
]
[[package]]
name = "mime"
version = "0.3.14"
@ -2070,6 +2080,12 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]]
name = "nom"
version = "1.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
[[package]]
name = "nom"
version = "4.2.3"
@ -2170,6 +2186,7 @@ dependencies = [
"itertools 0.8.2",
"language-reporting",
"log",
"meval",
"natural",
"nom 5.1.0",
"nom-tracable",

View file

@ -123,6 +123,7 @@ termcolor = "1.1.0"
natural = "0.3.0"
parking_lot = "0.10.0"
futures-timer = "1.0.2"
meval = "0.2"
clipboard = {version = "0.5", optional = true }
ptree = {version = "0.2" }

View file

@ -268,6 +268,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
whole_stream_command(Save),
per_item_command(Cpy),
whole_stream_command(Date),
per_item_command(Calc),
per_item_command(Mkdir),
per_item_command(Move),
whole_stream_command(Version),

View file

@ -7,6 +7,7 @@ mod to_delimited_data;
pub(crate) mod append;
pub(crate) mod args;
pub(crate) mod autoview;
pub(crate) mod calc;
pub(crate) mod cd;
pub(crate) mod classified;
pub(crate) mod clip;
@ -107,6 +108,7 @@ pub(crate) use command::{
};
pub(crate) use append::Append;
pub(crate) use calc::Calc;
pub(crate) use compact::Compact;
pub(crate) use config::Config;
pub(crate) use count::Count;

57
src/commands/calc.rs Normal file
View file

@ -0,0 +1,57 @@
use crate::commands::PerItemCommand;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{CallInfo, Primitive, ReturnSuccess, UntaggedValue, Value};
pub struct Calc;
impl PerItemCommand for Calc {
fn name(&self) -> &str {
"calc"
}
fn usage(&self) -> &str {
"Parse a math expression into a number"
}
fn run(
&self,
_call_info: &CallInfo,
_registry: &CommandRegistry,
raw_args: &RawCommandArgs,
input: Value,
) -> Result<OutputStream, ShellError> {
calc(input, raw_args)
}
}
fn calc(input: Value, args: &RawCommandArgs) -> Result<OutputStream, ShellError> {
let name_span = &args.call_info.name_tag.span;
let output = if let Ok(string) = input.as_string() {
match parse(&string, &input.tag) {
Ok(value) => ReturnSuccess::value(value),
Err(err) => Err(ShellError::labeled_error(
"Calulation error",
err,
&input.tag.span,
)),
}
} else {
Err(ShellError::labeled_error(
"Expected a string from pipeline",
"requires string input",
name_span,
))
};
Ok(vec![output].into())
}
pub fn parse(math_expression: &str, tag: impl Into<Tag>) -> Result<Value, String> {
let num = meval::eval_str(math_expression);
match num {
Ok(num) => Ok(UntaggedValue::from(Primitive::from(num)).into_value(tag)),
Err(error) => Err(error.to_string()),
}
}

49
tests/commands/calc.rs Normal file
View file

@ -0,0 +1,49 @@
use nu_test_support::{nu, pipeline};
#[test]
fn calculates_two_plus_two() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "2 + 2" | calc
"#
));
assert!(actual.contains("4.0"));
}
#[test]
fn calculates_two_to_the_power_six() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "2 ^ 6" | calc
"#
));
assert!(actual.contains("64.0"));
}
#[test]
fn calculates_three_multiplied_by_five() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "3 * 5" | calc
"#
));
assert!(actual.contains("15.0"));
}
#[test]
fn calculates_twenty_four_divided_by_two() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo "24 / 2" | calc
"#
));
assert!(actual.contains("12.0"));
}

View file

@ -1,4 +1,5 @@
mod append;
mod calc;
mod cd;
mod compact;
mod cp;