diff --git a/crates/nu-command/src/filters/length.rs b/crates/nu-command/src/filters/length.rs index 3d7b739ef2..b643c4dfea 100644 --- a/crates/nu-command/src/filters/length.rs +++ b/crates/nu-command/src/filters/length.rs @@ -19,6 +19,7 @@ impl Command for Length { .input_output_types(vec![ (Type::List(Box::new(Type::Any)), Type::Int), (Type::Binary, Type::Int), + (Type::Nothing, Type::Int), ]) .category(Category::Filters) } @@ -54,6 +55,11 @@ impl Command for Length { example: "0x[01 02] | length", result: Some(Value::test_int(2)), }, + Example { + description: "Count the length a null value", + example: "null | length", + result: Some(Value::test_int(0)), + }, ] } } @@ -61,23 +67,19 @@ impl Command for Length { fn length_row(call: &Call, input: PipelineData) -> Result { let span = input.span().unwrap_or(call.head); match input { - PipelineData::Value(Value::Nothing { .. }, ..) => { + PipelineData::Empty | PipelineData::Value(Value::Nothing { .. }, ..) => { Ok(Value::int(0, call.head).into_pipeline_data()) } - // I added this here because input_output_type() wasn't catching a record - // being sent in as input from echo. e.g. "echo {a:1 b:2} | length" - PipelineData::Value(Value::Record { .. }, ..) => { - Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "list, and table".into(), - wrong_type: "record".into(), - dst_span: call.head, - src_span: span, - }) - } PipelineData::Value(Value::Binary { val, .. }, ..) => { Ok(Value::int(val.len() as i64, call.head).into_pipeline_data()) } - PipelineData::ByteStream(stream, _) if stream.type_().is_binary_coercible() => { + PipelineData::Value(Value::List { vals, .. }, ..) => { + Ok(Value::int(vals.len() as i64, call.head).into_pipeline_data()) + } + PipelineData::ListStream(stream, ..) => { + Ok(Value::int(stream.into_iter().count() as i64, call.head).into_pipeline_data()) + } + PipelineData::ByteStream(stream, ..) if stream.type_().is_binary_coercible() => { Ok(Value::int( match stream.reader() { Some(r) => r.bytes().count() as i64, @@ -87,17 +89,12 @@ fn length_row(call: &Call, input: PipelineData) -> Result { - let mut count: i64 = 0; - // Check for and propagate errors - for value in input.into_iter() { - if let Value::Error { error, .. } = value { - return Err(*error); - } - count += 1 - } - Ok(Value::int(count, call.head).into_pipeline_data()) - } + _ => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "list, table, binary, and nothing".into(), + wrong_type: input.get_type().to_string(), + dst_span: call.head, + src_span: span, + }), } }