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

View File

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

View File

@ -1537,6 +1537,13 @@ impl Value {
return lhs.operation(*span, Operator::LessThan, op, rhs); 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) { match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool { Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Less), val: matches!(ordering, Ordering::Less),
@ -1558,6 +1565,13 @@ impl Value {
return lhs.operation(*span, Operator::LessThanOrEqual, op, rhs); 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) { match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool { Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Less | Ordering::Equal), val: matches!(ordering, Ordering::Less | Ordering::Equal),
@ -1579,6 +1593,13 @@ impl Value {
return lhs.operation(*span, Operator::GreaterThan, op, rhs); 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) { match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool { Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Greater), val: matches!(ordering, Ordering::Greater),
@ -1600,6 +1621,13 @@ impl Value {
return lhs.operation(*span, Operator::GreaterThanOrEqual, op, rhs); 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) { match self.partial_cmp(rhs) {
Some(ordering) => Ok(Value::Bool { Some(ordering) => Ok(Value::Bool {
val: matches!(ordering, Ordering::Greater | Ordering::Equal), 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 /// Create a Value::Record from a spanned indexmap
impl From<Spanned<IndexMap<String, Value>>> for Value { impl From<Spanned<IndexMap<String, Value>>> for Value {
fn from(input: Spanned<IndexMap<String, Value>>) -> Self { fn from(input: Spanned<IndexMap<String, Value>>) -> Self {