Repository: nushell/nushell
File: crates/nu-command/src/help/help_operators.rs (Rust)

Code before:
        _input: PipelineData,
    ) -> Result<PipelineData, ShellError> {
        let head = call.head;
        let mut operators = [
            Operator::Assignment(Assignment::Assign),
            Operator::Assignment(Assignment::AddAssign),
            Operator::Assignment(Assignment::SubtractAssign),
            Operator::Assignment(Assignment::MultiplyAssign),
            Operator::Assignment(Assignment::DivideAssign),
            Operator::Assignment(Assignment::ConcatenateAssign),
            Operator::Comparison(Comparison::Equal),
            Operator::Comparison(Comparison::NotEqual),
            Operator::Comparison(Comparison::LessThan),
            Operator::Comparison(Comparison::GreaterThan),
            Operator::Comparison(Comparison::LessThanOrEqual),
            Operator::Comparison(Comparison::GreaterThanOrEqual),
            Operator::Comparison(Comparison::RegexMatch),
            Operator::Comparison(Comparison::NotRegexMatch),
            Operator::Comparison(Comparison::In),
            Operator::Comparison(Comparison::NotIn),
            Operator::Comparison(Comparison::Has),
            Operator::Comparison(Comparison::NotHas),
            Operator::Comparison(Comparison::StartsWith),
            Operator::Comparison(Comparison::NotStartsWith),
            Operator::Comparison(Comparison::EndsWith),
            Operator::Comparison(Comparison::NotEndsWith),
            Operator::Math(Math::Add),
            Operator::Math(Math::Subtract),
            Operator::Math(Math::Multiply),
            Operator::Math(Math::Divide),
            Operator::Math(Math::FloorDivide),
            Operator::Math(Math::Modulo),
            Operator::Math(Math::Pow),
            Operator::Math(Math::Concatenate),
            Operator::Bits(Bits::BitOr),
            Operator::Bits(Bits::BitXor),
            Operator::Bits(Bits::BitAnd),
            Operator::Bits(Bits::ShiftLeft),
            Operator::Bits(Bits::ShiftRight),
            Operator::Boolean(Boolean::Or),
            Operator::Boolean(Boolean::Xor),
            Operator::Boolean(Boolean::And),
        ]
        .into_iter()
        .map(|op| {
            if op == Operator::Comparison(Comparison::RegexMatch) {
                Value::record(
                    record! {
                        "type" => Value::string(op_type(&op), head),
                        "operator" => Value::string("=~, like", head),
                        "name" => Value::string(name(&op), head),

Review comment (refactor):
Would you please refactor this into an iterated version using the `strum` crate? So we don't have to manually do it for new operators in the future.

You can find an example here:
https://github.com/nushell/nushell/blob/ddafef92adbde70f76ae51a7582480e2a6fc24f1/crates/nu-cli/src/completions/operator_completions.rs#L40-L47

Code after:
        call: &Call,
        _input: PipelineData,
    ) -> Result<PipelineData, ShellError> {
        let head = call.head;
        let mut operators = Assignment::iter()
            .map(Operator::Assignment)
            .chain(Comparison::iter().map(Operator::Comparison))
            .chain(Math::iter().map(Operator::Math))
            .chain(Bits::iter().map(Operator::Bits))
            .chain(Boolean::iter().map(Operator::Boolean))
            .map(|op| {
                if op == Operator::Comparison(Comparison::RegexMatch) {
                    Value::record(
                        record! {
                            "type" => Value::string(op_type(&op), head),
                            "operator" => Value::string("=~, like", head),
                            "name" => Value::string(name(&op), head),
                            "description" => Value::string(description(&op), head),
                            "precedence" => Value::int(op.precedence().into(), head),
                        },
                        head,
                    )
                } else if op == Operator::Comparison(Comparison::NotRegexMatch) {
                    Value::record(
                        record! {
                            "type" => Value::string(op_type(&op), head),
                            "operator" => Value::string("!~, not-like", head),
                            "name" => Value::string(name(&op), head),
                            "description" => Value::string(description(&op), head),
                            "precedence" => Value::int(op.precedence().into(), head),
                        },
                        head,
                    )
                } else {
                    Value::record(
                        record! {
                            "type" => Value::string(op_type(&op), head),
                            "operator" => Value::string(op.to_string(), head),
                            "name" => Value::string(name(&op), head),
                            "description" => Value::string(description(&op), head),
                            "precedence" => Value::int(op.precedence().into(), head),
                        },
                        head,
                    )
                }
            })
            .collect::<Vec<_>>();

        operators.push(Value::record(
            record! {
                "type" => Value::string("Boolean", head),