mirror of
https://github.com/nushell/nushell.git
synced 2025-02-16 18:41:44 +01:00
Make a calc
command (#1280)
This commit is contained in:
parent
ac5ad45783
commit
dc3370b103
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -1927,6 +1927,16 @@ dependencies = [
|
|||||||
"rustc_version",
|
"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]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.14"
|
version = "0.3.14"
|
||||||
@ -2070,6 +2080,12 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "1.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "4.2.3"
|
version = "4.2.3"
|
||||||
@ -2170,6 +2186,7 @@ dependencies = [
|
|||||||
"itertools 0.8.2",
|
"itertools 0.8.2",
|
||||||
"language-reporting",
|
"language-reporting",
|
||||||
"log",
|
"log",
|
||||||
|
"meval",
|
||||||
"natural",
|
"natural",
|
||||||
"nom 5.1.0",
|
"nom 5.1.0",
|
||||||
"nom-tracable",
|
"nom-tracable",
|
||||||
|
@ -123,6 +123,7 @@ termcolor = "1.1.0"
|
|||||||
natural = "0.3.0"
|
natural = "0.3.0"
|
||||||
parking_lot = "0.10.0"
|
parking_lot = "0.10.0"
|
||||||
futures-timer = "1.0.2"
|
futures-timer = "1.0.2"
|
||||||
|
meval = "0.2"
|
||||||
|
|
||||||
clipboard = {version = "0.5", optional = true }
|
clipboard = {version = "0.5", optional = true }
|
||||||
ptree = {version = "0.2" }
|
ptree = {version = "0.2" }
|
||||||
|
@ -268,6 +268,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||||||
whole_stream_command(Save),
|
whole_stream_command(Save),
|
||||||
per_item_command(Cpy),
|
per_item_command(Cpy),
|
||||||
whole_stream_command(Date),
|
whole_stream_command(Date),
|
||||||
|
per_item_command(Calc),
|
||||||
per_item_command(Mkdir),
|
per_item_command(Mkdir),
|
||||||
per_item_command(Move),
|
per_item_command(Move),
|
||||||
whole_stream_command(Version),
|
whole_stream_command(Version),
|
||||||
|
@ -7,6 +7,7 @@ mod to_delimited_data;
|
|||||||
pub(crate) mod append;
|
pub(crate) mod append;
|
||||||
pub(crate) mod args;
|
pub(crate) mod args;
|
||||||
pub(crate) mod autoview;
|
pub(crate) mod autoview;
|
||||||
|
pub(crate) mod calc;
|
||||||
pub(crate) mod cd;
|
pub(crate) mod cd;
|
||||||
pub(crate) mod classified;
|
pub(crate) mod classified;
|
||||||
pub(crate) mod clip;
|
pub(crate) mod clip;
|
||||||
@ -107,6 +108,7 @@ pub(crate) use command::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use append::Append;
|
pub(crate) use append::Append;
|
||||||
|
pub(crate) use calc::Calc;
|
||||||
pub(crate) use compact::Compact;
|
pub(crate) use compact::Compact;
|
||||||
pub(crate) use config::Config;
|
pub(crate) use config::Config;
|
||||||
pub(crate) use count::Count;
|
pub(crate) use count::Count;
|
||||||
|
57
src/commands/calc.rs
Normal file
57
src/commands/calc.rs
Normal 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
49
tests/commands/calc.rs
Normal 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"));
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
mod append;
|
mod append;
|
||||||
|
mod calc;
|
||||||
mod cd;
|
mod cd;
|
||||||
mod compact;
|
mod compact;
|
||||||
mod cp;
|
mod cp;
|
||||||
|
Loading…
Reference in New Issue
Block a user