1use crate::math::{
2 reducers::{Reduce, reducer_for},
3 utils::{run_with_function_with_cell_paths, run_with_function_with_cell_paths_const},
4};
5use nu_engine::command_prelude::*;
6
7#[derive(Clone)]
8pub struct MathMax;
9
10impl Command for MathMax {
11 fn name(&self) -> &str {
12 "math max"
13 }
14
15 fn signature(&self) -> Signature {
16 Signature::build("math max")
17 .input_output_types(vec![
18 (Type::List(Box::new(Type::Number)), Type::Number),
19 (Type::List(Box::new(Type::Duration)), Type::Duration),
20 (Type::List(Box::new(Type::Filesize)), Type::Filesize),
21 (Type::List(Box::new(Type::Any)), Type::Any),
22 (Type::Range, Type::Number),
23 (Type::table(), Type::record()),
24 (Type::record(), Type::record()),
25 ])
26 .allow_variants_without_examples(true)
27 .rest(
28 "columns",
29 SyntaxShape::CellPath,
30 "The cell-paths/columns to operate on.",
31 )
32 .category(Category::Math)
33 }
34
35 fn description(&self) -> &str {
36 "Returns the maximum of a list of values, or of columns in a table."
37 }
38
39 fn search_terms(&self) -> Vec<&str> {
40 vec!["maximum", "largest"]
41 }
42
43 fn is_const(&self) -> bool {
44 true
45 }
46
47 fn run(
48 &self,
49 engine_state: &EngineState,
50 stack: &mut Stack,
51 call: &Call,
52 input: PipelineData,
53 ) -> Result<PipelineData, ShellError> {
54 run_with_function_with_cell_paths(engine_state, stack, call, input, maximum)
55 }
56
57 fn run_const(
58 &self,
59 working_set: &StateWorkingSet,
60 call: &Call,
61 input: PipelineData,
62 ) -> Result<PipelineData, ShellError> {
63 run_with_function_with_cell_paths_const(working_set, call, input, maximum)
64 }
65
66 fn examples(&self) -> Vec<Example<'_>> {
67 vec![
68 Example {
69 description: "Find the maximum of a list of numbers.",
70 example: "[-50 100 25] | math max",
71 result: Some(Value::test_int(100)),
72 },
73 Example {
74 description: "Find the maxima of the columns of a table.",
75 example: "[{a: 1 b: 3} {a: 2 b: -1}] | math max",
76 result: Some(Value::test_record(record! {
77 "a" => Value::test_int(2),
78 "b" => Value::test_int(3),
79 })),
80 },
81 Example {
82 description: "Find the maximum of a list of dates.",
83 example: "[2022-02-02 2022-12-30 2012-12-12] | math max",
84 result: Some(Value::test_date(
85 "2022-12-30 00:00:00Z".parse().unwrap_or_default(),
86 )),
87 },
88 Example {
89 description: "Find the maximum of list-valued columns in a record.",
90 example: "{alice: [1 5 3], bob: [4 5 6]} | math max",
91 result: Some(Value::test_record(record! {
92 "alice" => Value::test_int(5),
93 "bob" => Value::test_int(6),
94 })),
95 },
96 Example {
97 description: "Find the maximum of a single column using a cell path.",
98 example: "{alice: [1 5 3], bob: [4 5 6]} | math max alice",
99 result: Some(Value::test_record(record! {
100 "alice" => Value::test_int(5),
101 "bob" => Value::list(
102 vec![Value::test_int(4), Value::test_int(5), Value::test_int(6)],
103 Span::test_data(),
104 ),
105 })),
106 },
107 ]
108 }
109}
110
111pub fn maximum(values: &[Value], span: Span, head: Span) -> Result<Value, ShellError> {
112 let max_func = reducer_for(Reduce::Maximum);
113 max_func(Value::nothing(head), values.to_vec(), span, head)
114}
115
116#[cfg(test)]
117mod test {
118 use super::*;
119
120 #[test]
121 fn test_examples() -> nu_test_support::Result {
122 nu_test_support::test().examples(MathMax)
123 }
124}