mirror of
https://github.com/nushell/nushell
synced 2025-01-02 16:29:00 +00:00
commit
6e92812cdf
11 changed files with 175 additions and 140 deletions
|
@ -61,7 +61,7 @@ impl Command for If {
|
||||||
Ok(Value::Nothing { span })
|
Ok(Value::Nothing { span })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::CantConvert("bool".into(), result.span())),
|
_ => Err(ShellError::CantConvert("bool".into(), result.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl Command for Each {
|
||||||
match input {
|
match input {
|
||||||
Value::Range { val, .. } => Ok(Value::Stream {
|
Value::Range { val, .. } => Ok(Value::Stream {
|
||||||
stream: val
|
stream: val
|
||||||
.into_iter()
|
.into_range_iter()?
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(idx, x)| {
|
.map(move |(idx, x)| {
|
||||||
let engine_state = context.engine_state.borrow();
|
let engine_state = context.engine_state.borrow();
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl Command for FromJson {
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: Value,
|
input: Value,
|
||||||
) -> Result<nu_protocol::Value, ShellError> {
|
) -> Result<nu_protocol::Value, ShellError> {
|
||||||
let span = input.span();
|
let span = input.span()?;
|
||||||
let mut string_input = input.collect_string();
|
let mut string_input = input.collect_string();
|
||||||
string_input.push('\n');
|
string_input.push('\n');
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,9 @@ fn split_chars(call: &Call, input: Value) -> Result<nu_protocol::Value, nu_proto
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
||||||
|
match v.span() {
|
||||||
|
Ok(v_span) => {
|
||||||
if let Ok(s) = v.as_string() {
|
if let Ok(s) = v.as_string() {
|
||||||
let v_span = v.span();
|
|
||||||
s.chars()
|
s.chars()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -83,11 +84,14 @@ fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
||||||
error: ShellError::PipelineMismatch {
|
error: ShellError::PipelineMismatch {
|
||||||
expected: Type::String,
|
expected: Type::String,
|
||||||
expected_span: name,
|
expected_span: name,
|
||||||
origin: v.span(),
|
origin: v_span,
|
||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(error) => vec![Value::Error { error }],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|
|
@ -109,12 +109,15 @@ fn split_column_helper(
|
||||||
span: head,
|
span: head,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Value::Error {
|
match v.span() {
|
||||||
|
Ok(span) => Value::Error {
|
||||||
error: ShellError::PipelineMismatch {
|
error: ShellError::PipelineMismatch {
|
||||||
expected: Type::String,
|
expected: Type::String,
|
||||||
expected_span: head,
|
expected_span: head,
|
||||||
origin: v.span(),
|
origin: span,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
Err(error) => Value::Error { error },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,8 @@ fn split_row(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<Value> {
|
fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<Value> {
|
||||||
|
match v.span() {
|
||||||
|
Ok(v_span) => {
|
||||||
if let Ok(s) = v.as_string() {
|
if let Ok(s) = v.as_string() {
|
||||||
let splitter = separator.item.replace("\\n", "\n");
|
let splitter = separator.item.replace("\\n", "\n");
|
||||||
s.split(&splitter)
|
s.split(&splitter)
|
||||||
|
@ -55,7 +57,7 @@ fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<V
|
||||||
if s.trim() != "" {
|
if s.trim() != "" {
|
||||||
Some(Value::String {
|
Some(Value::String {
|
||||||
val: s.into(),
|
val: s.into(),
|
||||||
span: v.span(),
|
span: v_span,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -67,11 +69,14 @@ fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<V
|
||||||
error: ShellError::PipelineMismatch {
|
error: ShellError::PipelineMismatch {
|
||||||
expected: Type::String,
|
expected: Type::String,
|
||||||
expected_span: name,
|
expected_span: name,
|
||||||
origin: v.span(),
|
origin: v_span,
|
||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(error) => vec![Value::Error { error }],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
// #[cfg(test)]
|
||||||
// mod tests {
|
// mod tests {
|
||||||
|
|
|
@ -45,7 +45,7 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = if let Some(rest_item) = rest_items.first() {
|
let span = if let Some(rest_item) = rest_items.first() {
|
||||||
rest_item.span()
|
rest_item.span()?
|
||||||
} else {
|
} else {
|
||||||
Span::unknown()
|
Span::unknown()
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl FromValue for Spanned<i64> {
|
||||||
span: *span,
|
span: *span,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
v => Err(ShellError::CantConvert("integer".into(), v.span())),
|
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ impl FromValue for i64 {
|
||||||
*val as i64,
|
*val as i64,
|
||||||
),
|
),
|
||||||
|
|
||||||
v => Err(ShellError::CantConvert("integer".into(), v.span())),
|
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ impl FromValue for Spanned<f64> {
|
||||||
span: *span,
|
span: *span,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
v => Err(ShellError::CantConvert("float".into(), v.span())),
|
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ impl FromValue for f64 {
|
||||||
match v {
|
match v {
|
||||||
Value::Float { val, .. } => Ok(*val),
|
Value::Float { val, .. } => Ok(*val),
|
||||||
Value::Int { val, .. } => Ok(*val as f64),
|
Value::Int { val, .. } => Ok(*val as f64),
|
||||||
v => Err(ShellError::CantConvert("float".into(), v.span())),
|
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ impl FromValue for Spanned<String> {
|
||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
Ok(Spanned {
|
Ok(Spanned {
|
||||||
item: v.clone().into_string(),
|
item: v.clone().into_string(),
|
||||||
span: v.span(),
|
span: v.span()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ impl FromValue for ColumnPath {
|
||||||
|
|
||||||
impl FromValue for CellPath {
|
impl FromValue for CellPath {
|
||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
let span = v.span();
|
let span = v.span()?;
|
||||||
match v {
|
match v {
|
||||||
Value::CellPath { val, .. } => Ok(val.clone()),
|
Value::CellPath { val, .. } => Ok(val.clone()),
|
||||||
Value::String { val, .. } => Ok(CellPath {
|
Value::String { val, .. } => Ok(CellPath {
|
||||||
|
@ -130,7 +130,7 @@ impl FromValue for CellPath {
|
||||||
span,
|
span,
|
||||||
}],
|
}],
|
||||||
}),
|
}),
|
||||||
v => Err(ShellError::CantConvert("cell path".into(), v.span())),
|
_ => Err(ShellError::CantConvert("cell path".into(), span)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ impl FromValue for bool {
|
||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
match v {
|
match v {
|
||||||
Value::Bool { val, .. } => Ok(*val),
|
Value::Bool { val, .. } => Ok(*val),
|
||||||
v => Err(ShellError::CantConvert("bool".into(), v.span())),
|
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ impl FromValue for Spanned<bool> {
|
||||||
item: *val,
|
item: *val,
|
||||||
span: *span,
|
span: *span,
|
||||||
}),
|
}),
|
||||||
v => Err(ShellError::CantConvert("bool".into(), v.span())),
|
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ impl FromValue for Range {
|
||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
match v {
|
match v {
|
||||||
Value::Range { val, .. } => Ok((**val).clone()),
|
Value::Range { val, .. } => Ok((**val).clone()),
|
||||||
v => Err(ShellError::CantConvert("range".into(), v.span())),
|
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ impl FromValue for Spanned<Range> {
|
||||||
item: (**val).clone(),
|
item: (**val).clone(),
|
||||||
span: *span,
|
span: *span,
|
||||||
}),
|
}),
|
||||||
v => Err(ShellError::CantConvert("range".into(), v.span())),
|
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,29 +90,29 @@ impl Value {
|
||||||
pub fn as_string(&self) -> Result<String, ShellError> {
|
pub fn as_string(&self) -> Result<String, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
Value::String { val, .. } => Ok(val.to_string()),
|
Value::String { val, .. } => Ok(val.to_string()),
|
||||||
_ => Err(ShellError::CantConvert("string".into(), self.span())),
|
_ => Err(ShellError::CantConvert("string".into(), self.span()?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the span for the current value
|
/// Get the span for the current value
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Result<Span, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
Value::Error { .. } => Span::unknown(),
|
Value::Error { error } => Err(error.clone()),
|
||||||
Value::Bool { span, .. } => *span,
|
Value::Bool { span, .. } => Ok(*span),
|
||||||
Value::Int { span, .. } => *span,
|
Value::Int { span, .. } => Ok(*span),
|
||||||
Value::Float { span, .. } => *span,
|
Value::Float { span, .. } => Ok(*span),
|
||||||
Value::Filesize { span, .. } => *span,
|
Value::Filesize { span, .. } => Ok(*span),
|
||||||
Value::Duration { span, .. } => *span,
|
Value::Duration { span, .. } => Ok(*span),
|
||||||
Value::Date { span, .. } => *span,
|
Value::Date { span, .. } => Ok(*span),
|
||||||
Value::Range { span, .. } => *span,
|
Value::Range { span, .. } => Ok(*span),
|
||||||
Value::String { span, .. } => *span,
|
Value::String { span, .. } => Ok(*span),
|
||||||
Value::Record { span, .. } => *span,
|
Value::Record { span, .. } => Ok(*span),
|
||||||
Value::List { span, .. } => *span,
|
Value::List { span, .. } => Ok(*span),
|
||||||
Value::Block { span, .. } => *span,
|
Value::Block { span, .. } => Ok(*span),
|
||||||
Value::Stream { span, .. } => *span,
|
Value::Stream { span, .. } => Ok(*span),
|
||||||
Value::Nothing { span, .. } => *span,
|
Value::Nothing { span, .. } => Ok(*span),
|
||||||
Value::Binary { span, .. } => *span,
|
Value::Binary { span, .. } => Ok(*span),
|
||||||
Value::CellPath { span, .. } => *span,
|
Value::CellPath { span, .. } => Ok(*span),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,15 +173,17 @@ impl Value {
|
||||||
Value::Filesize { val, .. } => format_filesize(val),
|
Value::Filesize { val, .. } => format_filesize(val),
|
||||||
Value::Duration { val, .. } => format_duration(val),
|
Value::Duration { val, .. } => format_duration(val),
|
||||||
Value::Date { val, .. } => HumanTime::from(val).to_string(),
|
Value::Date { val, .. } => HumanTime::from(val).to_string(),
|
||||||
Value::Range { val, .. } => {
|
Value::Range { val, .. } => match val.into_range_iter() {
|
||||||
|
Ok(iter) => {
|
||||||
format!(
|
format!(
|
||||||
"range: [{}]",
|
"range: [{}]",
|
||||||
val.into_iter()
|
iter.map(|x| x.into_string())
|
||||||
.map(|x| x.into_string())
|
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Err(error) => format!("{:?}", error),
|
||||||
|
},
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
Value::Stream { stream, .. } => stream.into_string(),
|
Value::Stream { stream, .. } => stream.into_string(),
|
||||||
Value::List { vals: val, .. } => format!(
|
Value::List { vals: val, .. } => format!(
|
||||||
|
@ -215,11 +217,15 @@ impl Value {
|
||||||
Value::Filesize { val, .. } => format!("{} bytes", val),
|
Value::Filesize { val, .. } => format!("{} bytes", val),
|
||||||
Value::Duration { val, .. } => format!("{} ns", val),
|
Value::Duration { val, .. } => format!("{} ns", val),
|
||||||
Value::Date { val, .. } => format!("{:?}", val),
|
Value::Date { val, .. } => format!("{:?}", val),
|
||||||
Value::Range { val, .. } => val
|
Value::Range { val, .. } => match val.into_range_iter() {
|
||||||
.into_iter()
|
Ok(iter) => iter
|
||||||
.map(|x| x.into_string())
|
.map(|x| x.into_string())
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
|
Err(error) => {
|
||||||
|
format!("{:?}", error)
|
||||||
|
}
|
||||||
|
},
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
Value::Stream { stream, .. } => stream.collect_string(),
|
Value::Stream { stream, .. } => stream.collect_string(),
|
||||||
Value::List { vals: val, .. } => val
|
Value::List { vals: val, .. } => val
|
||||||
|
@ -380,7 +386,7 @@ impl Value {
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
Value::Range { val, .. } => Ok(Value::Stream {
|
Value::Range { val, .. } => Ok(Value::Stream {
|
||||||
stream: val.into_iter().map(f).into_value_stream(),
|
stream: val.into_range_iter()?.map(f).into_value_stream(),
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
v => {
|
v => {
|
||||||
|
@ -409,10 +415,13 @@ impl Value {
|
||||||
stream: stream.map(f).flatten().into_value_stream(),
|
stream: stream.map(f).flatten().into_value_stream(),
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
Value::Range { val, .. } => Value::Stream {
|
Value::Range { val, .. } => match val.into_range_iter() {
|
||||||
stream: val.into_iter().map(f).flatten().into_value_stream(),
|
Ok(iter) => Value::Stream {
|
||||||
|
stream: iter.map(f).flatten().into_value_stream(),
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
|
Err(error) => Value::Error { error },
|
||||||
|
},
|
||||||
v => Value::Stream {
|
v => Value::Stream {
|
||||||
stream: f(v).into_iter().into_value_stream(),
|
stream: f(v).into_iter().into_value_stream(),
|
||||||
span,
|
span,
|
||||||
|
@ -506,7 +515,7 @@ impl PartialEq for Value {
|
||||||
|
|
||||||
impl Value {
|
impl Value {
|
||||||
pub fn add(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn add(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
||||||
|
@ -545,14 +554,14 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn sub(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn sub(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
||||||
|
@ -587,14 +596,14 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn mul(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn mul(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
|
||||||
|
@ -617,14 +626,14 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn div(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn div(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
|
||||||
|
@ -678,14 +687,14 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn lt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn lt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -695,14 +704,14 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn lte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn lte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -712,14 +721,14 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn gt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn gt(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -729,14 +738,14 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn gte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn gte(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -746,14 +755,14 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn eq(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn eq(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -763,14 +772,14 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn ne(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn ne(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match self.partial_cmp(rhs) {
|
match self.partial_cmp(rhs) {
|
||||||
Some(ordering) => Ok(Value::Bool {
|
Some(ordering) => Ok(Value::Bool {
|
||||||
|
@ -780,15 +789,15 @@ impl Value {
|
||||||
None => Err(ShellError::OperatorMismatch {
|
None => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn r#in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn r#in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
@ -814,15 +823,15 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn not_in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
pub fn not_in(&self, op: Span, rhs: &Value) -> Result<Value, ShellError> {
|
||||||
let span = span(&[self.span(), rhs.span()]);
|
let span = span(&[self.span()?, rhs.span()?]);
|
||||||
|
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
(lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool {
|
||||||
|
@ -848,9 +857,9 @@ impl Value {
|
||||||
_ => Err(ShellError::OperatorMismatch {
|
_ => Err(ShellError::OperatorMismatch {
|
||||||
op_span: op,
|
op_span: op,
|
||||||
lhs_ty: self.get_type(),
|
lhs_ty: self.get_type(),
|
||||||
lhs_span: self.span(),
|
lhs_span: self.span()?,
|
||||||
rhs_ty: rhs.get_type(),
|
rhs_ty: rhs.get_type(),
|
||||||
rhs_span: rhs.span(),
|
rhs_span: rhs.span()?,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,20 +122,26 @@ impl Range {
|
||||||
(_, _) => false,
|
(_, _) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl IntoIterator for Range {
|
pub fn into_range_iter(self) -> Result<RangeIterator, ShellError> {
|
||||||
type Item = Value;
|
let span = self.from.span()?;
|
||||||
|
|
||||||
type IntoIter = RangeIterator;
|
Ok(RangeIterator::new(self, span))
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
|
||||||
let span = self.from.span();
|
|
||||||
|
|
||||||
RangeIterator::new(self, span)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl IntoIterator for Range {
|
||||||
|
// type Item = Value;
|
||||||
|
|
||||||
|
// type IntoIter = RangeIterator;
|
||||||
|
|
||||||
|
// fn into_iter(self) -> Self::IntoIter {
|
||||||
|
// let span = self.from.span();
|
||||||
|
|
||||||
|
// RangeIterator::new(self, span)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
pub struct RangeIterator {
|
pub struct RangeIterator {
|
||||||
curr: Value,
|
curr: Value,
|
||||||
end: Value,
|
end: Value,
|
||||||
|
|
|
@ -658,3 +658,11 @@ fn string_not_in_string() -> TestResult {
|
||||||
fn float_not_in_inc_range() -> TestResult {
|
fn float_not_in_inc_range() -> TestResult {
|
||||||
run_test(r#"1.4 not-in 2..9.42"#, "true")
|
run_test(r#"1.4 not-in 2..9.42"#, "true")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn earlier_errors() -> TestResult {
|
||||||
|
fail_test(
|
||||||
|
r#"[1, "bob"] | each { $it + 3 } | each { $it / $it } | table"#,
|
||||||
|
"int",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue