Improve comparison errors (#4541)

This commit is contained in:
JT 2022-02-18 17:11:27 -05:00 committed by GitHub
parent f085bd97f6
commit d53eaac7a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 23 deletions

View file

@ -1,7 +1,9 @@
use nu_engine::{eval_block_with_redirect, CallExt};
use nu_protocol::ast::Call;
use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack};
use nu_protocol::{Category, Example, PipelineData, Signature, SyntaxShape};
use nu_protocol::{
Category, Example, IntoInterruptiblePipelineData, PipelineData, Signature, SyntaxShape, Value,
};
#[derive(Clone)]
pub struct Where;
@ -39,29 +41,35 @@ impl Command for Where {
let ctrlc = engine_state.ctrlc.clone();
let engine_state = engine_state.clone();
input
.filter(
move |value| {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
stack.add_var(*var_id, value.clone());
Ok(input
.into_iter()
.filter_map(move |value| {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
stack.add_var(*var_id, value.clone());
}
}
let result = eval_block_with_redirect(
&engine_state,
&mut stack,
&block,
PipelineData::new(span),
);
match result {
Ok(result) => {
let result = result.into_value(span);
if result.is_true() {
Some(value)
} else {
None
}
}
let result = eval_block_with_redirect(
&engine_state,
&mut stack,
&block,
PipelineData::new(span),
);
match result {
Ok(result) => result.into_value(span).is_true(),
_ => false,
}
},
ctrlc,
)
.map(|x| x.set_metadata(metadata))
Err(err) => Some(Value::Error { error: err }),
}
})
.into_pipeline_data(ctrlc))
.map(|x| x.set_metadata(metadata))
}
fn examples(&self) -> Vec<Example> {

View file

@ -127,7 +127,7 @@ fn converts_to_int() {
| into int number_as_string
| rename number
| where number == 1
| get number
| get number.0
"#
));

View file

@ -1537,6 +1537,13 @@ impl Value {
return lhs.operation(*span, Operator::LessThan, op, rhs);
}
if !type_compatible(self.get_type(), rhs.get_type())
&& (self.get_type() != Type::Unknown)
&& (rhs.get_type() != Type::Unknown)
{
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
}
match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Less),
@ -1558,6 +1565,13 @@ impl Value {
return lhs.operation(*span, Operator::LessThanOrEqual, op, rhs);
}
if !type_compatible(self.get_type(), rhs.get_type())
&& (self.get_type() != Type::Unknown)
&& (rhs.get_type() != Type::Unknown)
{
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
}
match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Less | Ordering::Equal),
@ -1579,6 +1593,13 @@ impl Value {
return lhs.operation(*span, Operator::GreaterThan, op, rhs);
}
if !type_compatible(self.get_type(), rhs.get_type())
&& (self.get_type() != Type::Unknown)
&& (rhs.get_type() != Type::Unknown)
{
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
}
match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Greater),
@ -1600,6 +1621,13 @@ impl Value {
return lhs.operation(*span, Operator::GreaterThanOrEqual, op, rhs);
}
if !type_compatible(self.get_type(), rhs.get_type())
&& (self.get_type() != Type::Unknown)
&& (rhs.get_type() != Type::Unknown)
{
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
}
match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Greater | Ordering::Equal),
@ -1985,6 +2013,14 @@ impl From<Spanned<HashMap<String, Value>>> for Value {
}
}
fn type_compatible(a: Type, b: Type) -> bool {
if a == b {
return true;
}
matches!((a, b), (Type::Int, Type::Float) | (Type::Float, Type::Int))
}
/// Create a Value::Record from a spanned indexmap
impl From<Spanned<IndexMap<String, Value>>> for Value {
fn from(input: Spanned<IndexMap<String, Value>>) -> Self {