forked from extern/nushell
Switch tables to list/streams of records
This commit is contained in:
parent
2055b83c34
commit
b0ab78a767
2
TODO.md
2
TODO.md
@ -23,7 +23,7 @@
|
|||||||
- [ ] Source
|
- [ ] Source
|
||||||
- [ ] Autoenv
|
- [ ] Autoenv
|
||||||
- [ ] Externals
|
- [ ] Externals
|
||||||
- [ ] let [first, rest] = [1, 2, 3]
|
- [ ] let [first, rest] = [1, 2, 3] (design question: how do you pattern match a table?)
|
||||||
|
|
||||||
## Maybe:
|
## Maybe:
|
||||||
- [ ] default param values?
|
- [ ] default param values?
|
||||||
|
@ -348,9 +348,9 @@ pub fn report_shell_error(
|
|||||||
let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?;
|
let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?;
|
||||||
|
|
||||||
Diagnostic::error()
|
Diagnostic::error()
|
||||||
.with_message("Data cannot be accessed with a column path")
|
.with_message("Data cannot be accessed with a cell path")
|
||||||
.with_labels(vec![Label::primary(diag_file_id, diag_range)
|
.with_labels(vec![Label::primary(diag_file_id, diag_range)
|
||||||
.with_message(format!("{} doesn't support column paths", name))])
|
.with_message(format!("{} doesn't support cell paths", name))])
|
||||||
}
|
}
|
||||||
ShellError::CantFindColumn(span) => {
|
ShellError::CantFindColumn(span) => {
|
||||||
let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?;
|
let (diag_file_id, diag_range) = convert_span_to_diag(working_set, span)?;
|
||||||
|
@ -52,7 +52,7 @@ impl Command for Each {
|
|||||||
.into_value_stream(),
|
.into_value_stream(),
|
||||||
span: call.head,
|
span: call.head,
|
||||||
}),
|
}),
|
||||||
Value::List { val, .. } => Ok(Value::ValueStream {
|
Value::List { vals: val, .. } => Ok(Value::ValueStream {
|
||||||
stream: val
|
stream: val
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
@ -95,8 +95,6 @@ impl Command for Each {
|
|||||||
.into_value_stream(),
|
.into_value_stream(),
|
||||||
span: call.head,
|
span: call.head,
|
||||||
}),
|
}),
|
||||||
Value::RowStream { .. } => panic!("iterating row streams is not yet supported"),
|
|
||||||
Value::Table { .. } => panic!("table iteration not yet supported"),
|
|
||||||
x => {
|
x => {
|
||||||
//TODO: we need to watch to make sure this is okay
|
//TODO: we need to watch to make sure this is okay
|
||||||
let engine_state = context.engine_state.borrow();
|
let engine_state = context.engine_state.borrow();
|
||||||
|
@ -68,8 +68,8 @@ impl Command for For {
|
|||||||
.into_value_stream(),
|
.into_value_stream(),
|
||||||
span: call.head,
|
span: call.head,
|
||||||
}),
|
}),
|
||||||
Value::List { val, .. } => Ok(Value::List {
|
Value::List { vals: val, .. } => Ok(Value::List {
|
||||||
val: val
|
vals: val
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
let engine_state = context.engine_state.borrow();
|
let engine_state = context.engine_state.borrow();
|
||||||
|
@ -24,15 +24,7 @@ impl Command for Length {
|
|||||||
input: Value,
|
input: Value,
|
||||||
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||||
match input {
|
match input {
|
||||||
Value::List { val, .. } => {
|
Value::List { vals: val, .. } => {
|
||||||
let length = val.len();
|
|
||||||
|
|
||||||
Ok(Value::Int {
|
|
||||||
val: length as i64,
|
|
||||||
span: call.head,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Value::Table { val, .. } => {
|
|
||||||
let length = val.len();
|
let length = val.len();
|
||||||
|
|
||||||
Ok(Value::Int {
|
Ok(Value::Int {
|
||||||
@ -48,14 +40,6 @@ impl Command for Length {
|
|||||||
span: call.head,
|
span: call.head,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Value::RowStream { stream, .. } => {
|
|
||||||
let length = stream.count();
|
|
||||||
|
|
||||||
Ok(Value::Int {
|
|
||||||
val: length as i64,
|
|
||||||
span: call.head,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Value::Nothing { .. } => Ok(Value::Int {
|
Value::Nothing { .. } => Ok(Value::Int {
|
||||||
val: 0,
|
val: 0,
|
||||||
span: call.head,
|
span: call.head,
|
||||||
|
@ -55,7 +55,7 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
|
|||||||
.var_id
|
.var_id
|
||||||
.expect("Internal error: rest positional parameter lacks var_id"),
|
.expect("Internal error: rest positional parameter lacks var_id"),
|
||||||
Value::List {
|
Value::List {
|
||||||
val: rest_items,
|
vals: rest_items,
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -133,7 +133,7 @@ pub fn eval_expression(
|
|||||||
Expr::FullCellPath(column_path) => {
|
Expr::FullCellPath(column_path) => {
|
||||||
let value = eval_expression(context, &column_path.head)?;
|
let value = eval_expression(context, &column_path.head)?;
|
||||||
|
|
||||||
value.follow_column_path(&column_path.tail)
|
value.follow_cell_path(&column_path.tail)
|
||||||
}
|
}
|
||||||
Expr::Call(call) => eval_call(context, call, Value::nothing()),
|
Expr::Call(call) => eval_call(context, call, Value::nothing()),
|
||||||
Expr::ExternalCall(_, _) => Err(ShellError::ExternalNotSupported(expr.span)),
|
Expr::ExternalCall(_, _) => Err(ShellError::ExternalNotSupported(expr.span)),
|
||||||
@ -176,7 +176,7 @@ pub fn eval_expression(
|
|||||||
output.push(eval_expression(context, expr)?);
|
output.push(eval_expression(context, expr)?);
|
||||||
}
|
}
|
||||||
Ok(Value::List {
|
Ok(Value::List {
|
||||||
val: output,
|
vals: output,
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -192,11 +192,14 @@ pub fn eval_expression(
|
|||||||
for expr in val {
|
for expr in val {
|
||||||
row.push(eval_expression(context, expr)?);
|
row.push(eval_expression(context, expr)?);
|
||||||
}
|
}
|
||||||
output_rows.push(row);
|
output_rows.push(Value::Record {
|
||||||
|
cols: output_headers.clone(),
|
||||||
|
vals: row,
|
||||||
|
span: expr.span,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Ok(Value::Table {
|
Ok(Value::List {
|
||||||
headers: output_headers,
|
vals: output_rows,
|
||||||
val: output_rows,
|
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1781,7 @@ pub fn parse_table_expression(
|
|||||||
Expression {
|
Expression {
|
||||||
expr: Expr::List(vec![]),
|
expr: Expr::List(vec![]),
|
||||||
span,
|
span,
|
||||||
ty: Type::Table,
|
ty: Type::List(Box::new(Type::Unknown)),
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
@ -1828,7 +1828,7 @@ pub fn parse_table_expression(
|
|||||||
Expression {
|
Expression {
|
||||||
expr: Expr::Table(table_headers, rows),
|
expr: Expr::Table(table_headers, rows),
|
||||||
span,
|
span,
|
||||||
ty: Type::Table,
|
ty: Type::List(Box::new(Type::Unknown)),
|
||||||
},
|
},
|
||||||
error,
|
error,
|
||||||
)
|
)
|
||||||
@ -1965,7 +1965,7 @@ pub fn parse_value(
|
|||||||
// First, check the special-cases. These will likely represent specific values as expressions
|
// First, check the special-cases. These will likely represent specific values as expressions
|
||||||
// and may fit a variety of shapes.
|
// and may fit a variety of shapes.
|
||||||
//
|
//
|
||||||
// We check variable first because immediately following we check for variables with column paths
|
// We check variable first because immediately following we check for variables with cell paths
|
||||||
// which might result in a value that fits other shapes (and require the variable to already be
|
// which might result in a value that fits other shapes (and require the variable to already be
|
||||||
// declared)
|
// declared)
|
||||||
if shape == &SyntaxShape::Variable {
|
if shape == &SyntaxShape::Variable {
|
||||||
|
@ -29,17 +29,8 @@ impl EvaluationContext {
|
|||||||
// TODO: add ctrl-c support
|
// TODO: add ctrl-c support
|
||||||
|
|
||||||
let value = match value {
|
let value = match value {
|
||||||
Value::RowStream {
|
|
||||||
headers,
|
|
||||||
stream,
|
|
||||||
span,
|
|
||||||
} => Value::Table {
|
|
||||||
headers,
|
|
||||||
val: stream.collect(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
Value::ValueStream { stream, span } => Value::List {
|
Value::ValueStream { stream, span } => Value::List {
|
||||||
val: stream.collect(),
|
vals: stream.collect(),
|
||||||
span,
|
span,
|
||||||
},
|
},
|
||||||
x => x,
|
x => x,
|
||||||
|
@ -96,7 +96,7 @@ impl SyntaxShape {
|
|||||||
SyntaxShape::RowCondition => Type::Bool,
|
SyntaxShape::RowCondition => Type::Bool,
|
||||||
SyntaxShape::Signature => Type::Unknown,
|
SyntaxShape::Signature => Type::Unknown,
|
||||||
SyntaxShape::String => Type::String,
|
SyntaxShape::String => Type::String,
|
||||||
SyntaxShape::Table => Type::Table,
|
SyntaxShape::Table => Type::List(Box::new(Type::Unknown)), // FIXME
|
||||||
SyntaxShape::VarWithOptType => Type::Unknown,
|
SyntaxShape::VarWithOptType => Type::Unknown,
|
||||||
SyntaxShape::Variable => Type::Unknown,
|
SyntaxShape::Variable => Type::Unknown,
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ pub enum Type {
|
|||||||
List(Box<Type>),
|
List(Box<Type>),
|
||||||
Number,
|
Number,
|
||||||
Nothing,
|
Nothing,
|
||||||
Table,
|
Record(Vec<String>, Vec<Type>),
|
||||||
RowStream,
|
|
||||||
ValueStream,
|
ValueStream,
|
||||||
Unknown,
|
Unknown,
|
||||||
Error,
|
Error,
|
||||||
@ -34,13 +33,12 @@ impl Display for Type {
|
|||||||
Type::Float => write!(f, "float"),
|
Type::Float => write!(f, "float"),
|
||||||
Type::Int => write!(f, "int"),
|
Type::Int => write!(f, "int"),
|
||||||
Type::Range => write!(f, "range"),
|
Type::Range => write!(f, "range"),
|
||||||
|
Type::Record(cols, vals) => write!(f, "record<{}, {:?}>", cols.join(", "), vals),
|
||||||
Type::List(l) => write!(f, "list<{}>", l),
|
Type::List(l) => write!(f, "list<{}>", l),
|
||||||
Type::Nothing => write!(f, "nothing"),
|
Type::Nothing => write!(f, "nothing"),
|
||||||
Type::Number => write!(f, "number"),
|
Type::Number => write!(f, "number"),
|
||||||
Type::String => write!(f, "string"),
|
Type::String => write!(f, "string"),
|
||||||
Type::Table => write!(f, "table"),
|
|
||||||
Type::ValueStream => write!(f, "value stream"),
|
Type::ValueStream => write!(f, "value stream"),
|
||||||
Type::RowStream => write!(f, "row stream"),
|
|
||||||
Type::Unknown => write!(f, "unknown"),
|
Type::Unknown => write!(f, "unknown"),
|
||||||
Type::Error => write!(f, "error"),
|
Type::Error => write!(f, "error"),
|
||||||
}
|
}
|
||||||
|
@ -247,22 +247,17 @@ pub enum Value {
|
|||||||
val: String,
|
val: String,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
|
Record {
|
||||||
|
cols: Vec<String>,
|
||||||
|
vals: Vec<Value>,
|
||||||
|
span: Span,
|
||||||
|
},
|
||||||
ValueStream {
|
ValueStream {
|
||||||
stream: ValueStream,
|
stream: ValueStream,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
RowStream {
|
|
||||||
headers: Vec<String>,
|
|
||||||
stream: RowStream,
|
|
||||||
span: Span,
|
|
||||||
},
|
|
||||||
List {
|
List {
|
||||||
val: Vec<Value>,
|
vals: Vec<Value>,
|
||||||
span: Span,
|
|
||||||
},
|
|
||||||
Table {
|
|
||||||
headers: Vec<String>,
|
|
||||||
val: Vec<Vec<Value>>,
|
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
@ -292,10 +287,9 @@ impl Value {
|
|||||||
Value::Float { span, .. } => *span,
|
Value::Float { span, .. } => *span,
|
||||||
Value::Range { span, .. } => *span,
|
Value::Range { span, .. } => *span,
|
||||||
Value::String { span, .. } => *span,
|
Value::String { span, .. } => *span,
|
||||||
|
Value::Record { span, .. } => *span,
|
||||||
Value::List { span, .. } => *span,
|
Value::List { span, .. } => *span,
|
||||||
Value::Table { span, .. } => *span,
|
|
||||||
Value::Block { span, .. } => *span,
|
Value::Block { span, .. } => *span,
|
||||||
Value::RowStream { span, .. } => *span,
|
|
||||||
Value::ValueStream { span, .. } => *span,
|
Value::ValueStream { span, .. } => *span,
|
||||||
Value::Nothing { span, .. } => *span,
|
Value::Nothing { span, .. } => *span,
|
||||||
Value::Error { .. } => Span::unknown(),
|
Value::Error { .. } => Span::unknown(),
|
||||||
@ -309,10 +303,9 @@ impl Value {
|
|||||||
Value::Float { span, .. } => *span = new_span,
|
Value::Float { span, .. } => *span = new_span,
|
||||||
Value::Range { span, .. } => *span = new_span,
|
Value::Range { span, .. } => *span = new_span,
|
||||||
Value::String { span, .. } => *span = new_span,
|
Value::String { span, .. } => *span = new_span,
|
||||||
Value::RowStream { span, .. } => *span = new_span,
|
Value::Record { span, .. } => *span = new_span,
|
||||||
Value::ValueStream { span, .. } => *span = new_span,
|
Value::ValueStream { span, .. } => *span = new_span,
|
||||||
Value::List { span, .. } => *span = new_span,
|
Value::List { span, .. } => *span = new_span,
|
||||||
Value::Table { span, .. } => *span = new_span,
|
|
||||||
Value::Block { span, .. } => *span = new_span,
|
Value::Block { span, .. } => *span = new_span,
|
||||||
Value::Nothing { span, .. } => *span = new_span,
|
Value::Nothing { span, .. } => *span = new_span,
|
||||||
Value::Error { .. } => {}
|
Value::Error { .. } => {}
|
||||||
@ -328,12 +321,13 @@ impl Value {
|
|||||||
Value::Float { .. } => Type::Float,
|
Value::Float { .. } => Type::Float,
|
||||||
Value::Range { .. } => Type::Range,
|
Value::Range { .. } => Type::Range,
|
||||||
Value::String { .. } => Type::String,
|
Value::String { .. } => Type::String,
|
||||||
|
Value::Record { cols, vals, .. } => {
|
||||||
|
Type::Record(cols.clone(), vals.iter().map(|x| x.get_type()).collect())
|
||||||
|
}
|
||||||
Value::List { .. } => Type::List(Box::new(Type::Unknown)), // FIXME
|
Value::List { .. } => Type::List(Box::new(Type::Unknown)), // FIXME
|
||||||
Value::Table { .. } => Type::Table, // FIXME
|
|
||||||
Value::Nothing { .. } => Type::Nothing,
|
Value::Nothing { .. } => Type::Nothing,
|
||||||
Value::Block { .. } => Type::Block,
|
Value::Block { .. } => Type::Block,
|
||||||
Value::ValueStream { .. } => Type::ValueStream,
|
Value::ValueStream { .. } => Type::ValueStream,
|
||||||
Value::RowStream { .. } => Type::RowStream,
|
|
||||||
Value::Error { .. } => Type::Error,
|
Value::Error { .. } => Type::Error,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,29 +358,21 @@ impl Value {
|
|||||||
}
|
}
|
||||||
Value::String { val, .. } => val,
|
Value::String { val, .. } => val,
|
||||||
Value::ValueStream { stream, .. } => stream.into_string(),
|
Value::ValueStream { stream, .. } => stream.into_string(),
|
||||||
Value::List { val, .. } => format!(
|
Value::List { vals: val, .. } => format!(
|
||||||
"[{}]",
|
"[{}]",
|
||||||
val.into_iter()
|
val.into_iter()
|
||||||
.map(|x| x.into_string())
|
.map(|x| x.into_string())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
),
|
),
|
||||||
Value::Table { val, headers, .. } => format!(
|
Value::Record { cols, vals, .. } => format!(
|
||||||
"[= {} =\n {}]",
|
"{{{}}}",
|
||||||
headers.join(", "),
|
cols.iter()
|
||||||
val.into_iter()
|
.zip(vals.iter())
|
||||||
.map(|x| {
|
.map(|(x, y)| format!("{}: {}", x, y.clone().into_string()))
|
||||||
x.into_iter()
|
|
||||||
.map(|x| x.into_string())
|
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ")
|
.join(", ")
|
||||||
})
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
),
|
),
|
||||||
Value::RowStream {
|
|
||||||
headers, stream, ..
|
|
||||||
} => stream.into_string(headers),
|
|
||||||
Value::Block { val, .. } => format!("<Block {}>", val),
|
Value::Block { val, .. } => format!("<Block {}>", val),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error } => format!("{:?}", error),
|
Value::Error { error } => format!("{:?}", error),
|
||||||
@ -399,7 +385,7 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn follow_column_path(self, column_path: &[PathMember]) -> Result<Value, ShellError> {
|
pub fn follow_cell_path(self, column_path: &[PathMember]) -> Result<Value, ShellError> {
|
||||||
let mut current = self;
|
let mut current = self;
|
||||||
for member in column_path {
|
for member in column_path {
|
||||||
// FIXME: this uses a few extra clones for simplicity, but there may be a way
|
// FIXME: this uses a few extra clones for simplicity, but there may be a way
|
||||||
@ -411,7 +397,7 @@ impl Value {
|
|||||||
} => {
|
} => {
|
||||||
// Treat a numeric path member as `nth <val>`
|
// Treat a numeric path member as `nth <val>`
|
||||||
match &mut current {
|
match &mut current {
|
||||||
Value::List { val, .. } => {
|
Value::List { vals: val, .. } => {
|
||||||
if let Some(item) = val.get(*count) {
|
if let Some(item) = val.get(*count) {
|
||||||
current = item.clone();
|
current = item.clone();
|
||||||
} else {
|
} else {
|
||||||
@ -425,32 +411,6 @@ impl Value {
|
|||||||
return Err(ShellError::AccessBeyondEndOfStream(*origin_span));
|
return Err(ShellError::AccessBeyondEndOfStream(*origin_span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Table { headers, val, span } => {
|
|
||||||
if let Some(row) = val.get(*count) {
|
|
||||||
current = Value::Table {
|
|
||||||
headers: headers.clone(),
|
|
||||||
val: vec![row.clone()],
|
|
||||||
span: *span,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(ShellError::AccessBeyondEnd(val.len(), *origin_span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Value::RowStream {
|
|
||||||
headers,
|
|
||||||
stream,
|
|
||||||
span,
|
|
||||||
} => {
|
|
||||||
if let Some(row) = stream.nth(*count) {
|
|
||||||
current = Value::Table {
|
|
||||||
headers: headers.clone(),
|
|
||||||
val: vec![row.clone()],
|
|
||||||
span: *span,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(ShellError::AccessBeyondEndOfStream(*origin_span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x => {
|
x => {
|
||||||
return Err(ShellError::IncompatiblePathAccess(
|
return Err(ShellError::IncompatiblePathAccess(
|
||||||
format!("{}", x.get_type()),
|
format!("{}", x.get_type()),
|
||||||
@ -460,28 +420,15 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PathMember::String {
|
PathMember::String {
|
||||||
val,
|
val: column_name,
|
||||||
span: origin_span,
|
span: origin_span,
|
||||||
} => match &mut current {
|
} => match &mut current {
|
||||||
Value::Table {
|
Value::Record { cols, vals, .. } => {
|
||||||
headers,
|
|
||||||
val: cells,
|
|
||||||
span,
|
|
||||||
} => {
|
|
||||||
let mut found = false;
|
let mut found = false;
|
||||||
for header in headers.iter().enumerate() {
|
for col in cols.iter().zip(vals.iter()) {
|
||||||
if header.1 == val {
|
if col.0 == column_name {
|
||||||
|
current = col.1.clone();
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
let mut column = vec![];
|
|
||||||
for row in cells {
|
|
||||||
column.push(row[header.0].clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
current = Value::List {
|
|
||||||
val: column,
|
|
||||||
span: *span,
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,33 +437,22 @@ impl Value {
|
|||||||
return Err(ShellError::CantFindColumn(*origin_span));
|
return Err(ShellError::CantFindColumn(*origin_span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::RowStream {
|
Value::List { vals, span } => {
|
||||||
headers,
|
let mut output = vec![];
|
||||||
stream,
|
for val in vals {
|
||||||
span,
|
if let Value::Record { cols, vals, .. } = val {
|
||||||
} => {
|
for col in cols.iter().enumerate() {
|
||||||
let mut found = false;
|
if col.1 == column_name {
|
||||||
for header in headers.iter().enumerate() {
|
output.push(vals[col.0].clone());
|
||||||
if header.1 == val {
|
}
|
||||||
found = true;
|
}
|
||||||
|
}
|
||||||
let mut column = vec![];
|
|
||||||
for row in stream {
|
|
||||||
column.push(row[header.0].clone())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
current = Value::List {
|
current = Value::List {
|
||||||
val: column,
|
vals: output,
|
||||||
span: *span,
|
span: *span,
|
||||||
};
|
};
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !found {
|
|
||||||
//FIXME: add "did you mean"
|
|
||||||
return Err(ShellError::CantFindColumn(*origin_span));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
x => {
|
x => {
|
||||||
return Err(ShellError::IncompatiblePathAccess(
|
return Err(ShellError::IncompatiblePathAccess(
|
||||||
@ -844,19 +780,19 @@ impl Value {
|
|||||||
val: lhs == rhs,
|
val: lhs == rhs,
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(Value::List { val: lhs, .. }, Value::List { val: rhs, .. }) => Ok(Value::Bool {
|
(Value::List { vals: lhs, .. }, Value::List { vals: rhs, .. }) => Ok(Value::Bool {
|
||||||
val: lhs == rhs,
|
val: lhs == rhs,
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(
|
(
|
||||||
Value::Table {
|
Value::Record {
|
||||||
val: lhs,
|
vals: lhs,
|
||||||
headers: lhs_headers,
|
cols: lhs_headers,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
Value::Table {
|
Value::Record {
|
||||||
val: rhs,
|
vals: rhs,
|
||||||
headers: rhs_headers,
|
cols: rhs_headers,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) => Ok(Value::Bool {
|
) => Ok(Value::Bool {
|
||||||
@ -899,19 +835,19 @@ impl Value {
|
|||||||
val: lhs != rhs,
|
val: lhs != rhs,
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(Value::List { val: lhs, .. }, Value::List { val: rhs, .. }) => Ok(Value::Bool {
|
(Value::List { vals: lhs, .. }, Value::List { vals: rhs, .. }) => Ok(Value::Bool {
|
||||||
val: lhs != rhs,
|
val: lhs != rhs,
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
(
|
(
|
||||||
Value::Table {
|
Value::Record {
|
||||||
val: lhs,
|
vals: lhs,
|
||||||
headers: lhs_headers,
|
cols: lhs_headers,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
Value::Table {
|
Value::Record {
|
||||||
val: rhs,
|
vals: rhs,
|
||||||
headers: rhs_headers,
|
cols: rhs_headers,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
) => Ok(Value::Bool {
|
) => Ok(Value::Bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user