Update deprecation warnings (#15867)

# Description
- Use #15770 to
  - improve `get --sensitive` deprecation warning
  - add deprecation warning for `filter`
- refactor `filter` to use `where` as its implementation
- replace usages of `filter` with `where` in `std`

# User-Facing Changes
- `get --sensitive` will raise a warning only once, during parsing
whereas before it was raised during runtime for each usage.
- using `filter` will raise a deprecation warning, once

# Tests + Formatting
No existing test broke or required tweaking. Additional tests covering
this case was added.
- 🟢 toolkit fmt
- 🟢 toolkit clippy
- 🟢 toolkit test
- 🟢 toolkit test stdlib

# After Submitting
N/A

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
This commit is contained in:
Bahex
2025-06-01 19:21:07 +03:00
committed by GitHub
parent cfbe835910
commit ad9f051d61
6 changed files with 41 additions and 102 deletions

View File

@ -1,6 +1,5 @@
use super::utils::chain_error_with_input;
use nu_engine::{ClosureEval, ClosureEvalOnce, command_prelude::*};
use nu_protocol::engine::Closure;
use nu_engine::command_prelude::*;
use nu_protocol::{DeprecationEntry, DeprecationType, ReportMode};
#[derive(Clone)]
pub struct Filter;
@ -15,8 +14,8 @@ impl Command for Filter {
}
fn extra_description(&self) -> &str {
r#"This command works similar to 'where' but allows reading the predicate closure from
a variable. On the other hand, the "row condition" syntax is not supported."#
r#"This command works similar to 'where' but can only use a closure as a predicate.
The "row condition" syntax is not supported."#
}
fn signature(&self) -> nu_protocol::Signature {
@ -47,80 +46,20 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let head = call.head;
let closure: Closure = call.req(engine_state, stack, 0)?;
use super::where_::Where;
<Where as Command>::run(&Where, engine_state, stack, call, input)
}
let metadata = input.metadata();
match input {
PipelineData::Empty => Ok(PipelineData::Empty),
PipelineData::Value(Value::Range { .. }, ..)
| PipelineData::Value(Value::List { .. }, ..)
| PipelineData::ListStream(..) => {
let mut closure = ClosureEval::new(engine_state, stack, closure);
Ok(input
.into_iter()
.filter_map(move |value| {
match closure
.run_with_value(value.clone())
.and_then(|data| data.into_value(head))
{
Ok(cond) => cond.is_true().then_some(value),
Err(err) => {
let span = value.span();
let err = chain_error_with_input(err, value.is_error(), span);
Some(Value::error(err, span))
}
}
})
.into_pipeline_data(head, engine_state.signals().clone()))
fn deprecation_info(&self) -> Vec<nu_protocol::DeprecationEntry> {
vec![
DeprecationEntry {
ty: DeprecationType::Command,
report_mode: ReportMode::FirstUse,
since: Some("0.105.0".into()),
expected_removal: None,
help: Some("`where` command can be used instead, as it can now read the predicate closure from a variable".into()),
}
PipelineData::ByteStream(stream, ..) => {
if let Some(chunks) = stream.chunks() {
let mut closure = ClosureEval::new(engine_state, stack, closure);
Ok(chunks
.into_iter()
.filter_map(move |value| {
let value = match value {
Ok(value) => value,
Err(err) => return Some(Value::error(err, head)),
};
match closure
.run_with_value(value.clone())
.and_then(|data| data.into_value(head))
{
Ok(cond) => cond.is_true().then_some(value),
Err(err) => {
let span = value.span();
let err = chain_error_with_input(err, value.is_error(), span);
Some(Value::error(err, span))
}
}
})
.into_pipeline_data(head, engine_state.signals().clone()))
} else {
Ok(PipelineData::Empty)
}
}
// This match allows non-iterables to be accepted,
// which is currently considered undesirable (Nov 2022).
PipelineData::Value(value, ..) => {
let result = ClosureEvalOnce::new(engine_state, stack, closure)
.run_with_value(value.clone())
.and_then(|data| data.into_value(head));
Ok(match result {
Ok(cond) => cond.is_true().then_some(value),
Err(err) => {
let span = value.span();
let err = chain_error_with_input(err, value.is_error(), span);
Some(Value::error(err, span))
}
}
.into_pipeline_data(head, engine_state.signals().clone()))
}
}
.map(|data| data.set_metadata(metadata))
]
}
fn examples(&self) -> Vec<Example> {

View File

@ -1,7 +1,7 @@
use std::borrow::Cow;
use nu_engine::command_prelude::*;
use nu_protocol::{Signals, ast::PathMember, report_shell_warning};
use nu_protocol::{DeprecationEntry, DeprecationType, ReportMode, Signals, ast::PathMember};
#[derive(Clone)]
pub struct Get;
@ -132,19 +132,7 @@ If multiple cell paths are given, this will produce a list of values."#
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
let rest: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?;
let sensitive_span = call.get_flag_span(stack, "sensitive");
let metadata = input.metadata();
if let Some(span) = sensitive_span {
report_shell_warning(
engine_state,
&ShellError::Deprecated {
deprecated: "sensitive flag",
suggestion: "",
span,
help: Some("cell-paths are case-sensitive by default"),
},
);
}
action(
input,
cell_path,
@ -155,6 +143,18 @@ If multiple cell paths are given, this will produce a list of values."#
)
.map(|x| x.set_metadata(metadata))
}
fn deprecation_info(&self) -> Vec<DeprecationEntry> {
vec![
DeprecationEntry {
ty: DeprecationType::Flag("sensitive".into()),
report_mode: ReportMode::FirstUse,
since: Some("0.105.0".into()),
expected_removal: None,
help: Some("Cell-paths are now case-sensitive by default.\nTo access fields case-insensitively, add `!` after the relevant path member.".into())
}
]
}
}
fn action(

View File

@ -14,5 +14,5 @@ fn filter_with_return_in_closure() {
));
assert_eq!(actual.out, "[2, 4, 6, 8, 10]");
assert!(actual.err.is_empty());
assert!(actual.err.contains("deprecated"));
}