mirror of
https://github.com/nushell/nushell
synced 2025-01-14 06:04:09 +00:00
Try putting streams in Value
This commit is contained in:
parent
fcc1cd3d57
commit
c4c4d82bf4
4 changed files with 122 additions and 60 deletions
2
TODO.md
2
TODO.md
|
@ -12,10 +12,10 @@
|
||||||
- [x] subcommand alias
|
- [x] subcommand alias
|
||||||
- [x] type inference from successful parse (eg not `List<unknown>` but `List<int>`)
|
- [x] type inference from successful parse (eg not `List<unknown>` but `List<int>`)
|
||||||
- [x] parsing tables
|
- [x] parsing tables
|
||||||
|
- [ ] Column path
|
||||||
- [ ] ...rest without calling it rest
|
- [ ] ...rest without calling it rest
|
||||||
- [ ] operator overflow
|
- [ ] operator overflow
|
||||||
- [ ] finish operator type-checking
|
- [ ] finish operator type-checking
|
||||||
- [ ] Column path
|
|
||||||
- [ ] Ranges
|
- [ ] Ranges
|
||||||
- [ ] Source
|
- [ ] Source
|
||||||
- [ ] Autoenv
|
- [ ] Autoenv
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
use crate::{state::State, value::Value};
|
use crate::{
|
||||||
|
state::State,
|
||||||
|
value::{IntoRowStream, IntoValueStream, Value},
|
||||||
|
};
|
||||||
use nu_parser::{Block, Call, Expr, Expression, Operator, Span, Statement, Type};
|
use nu_parser::{Block, Call, Expr, Expression, Operator, Span, Statement, Type};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -124,7 +127,7 @@ fn eval_call(state: &State, call: &Call) -> Result<Value, ShellError> {
|
||||||
for expr in &call.positional {
|
for expr in &call.positional {
|
||||||
let val = eval_expression(state, expr)?;
|
let val = eval_expression(state, expr)?;
|
||||||
|
|
||||||
output.push(val.to_string());
|
output.push(val.into_string());
|
||||||
}
|
}
|
||||||
Ok(Value::String {
|
Ok(Value::String {
|
||||||
val: output.join(""),
|
val: output.join(""),
|
||||||
|
@ -259,7 +262,7 @@ pub fn eval_expression(state: &State, expr: &Expression) -> Result<Value, ShellE
|
||||||
output.push(eval_expression(state, expr)?);
|
output.push(eval_expression(state, expr)?);
|
||||||
}
|
}
|
||||||
Ok(Value::List {
|
Ok(Value::List {
|
||||||
val: output,
|
val: output.into_value_stream(),
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -279,7 +282,7 @@ pub fn eval_expression(state: &State, expr: &Expression) -> Result<Value, ShellE
|
||||||
}
|
}
|
||||||
Ok(Value::Table {
|
Ok(Value::Table {
|
||||||
headers: output_headers,
|
headers: output_headers,
|
||||||
val: output_rows,
|
val: output_rows.into_row_stream(),
|
||||||
span: expr.span,
|
span: expr.span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,105 @@
|
||||||
use std::fmt::Display;
|
use std::{cell::RefCell, fmt::Debug, rc::Rc};
|
||||||
|
|
||||||
use nu_parser::{BlockId, Span, Type};
|
use nu_parser::{BlockId, Span, Type};
|
||||||
|
|
||||||
use crate::ShellError;
|
use crate::ShellError;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ValueStream(Rc<RefCell<dyn Iterator<Item = Value>>>);
|
||||||
|
|
||||||
|
impl ValueStream {
|
||||||
|
pub fn into_string(self) -> String {
|
||||||
|
let val: Vec<Value> = self.collect();
|
||||||
|
format!(
|
||||||
|
"[{}]",
|
||||||
|
val.into_iter()
|
||||||
|
.map(|x| x.into_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ".into())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for ValueStream {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ValueStream").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for ValueStream {
|
||||||
|
type Item = Value;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
{
|
||||||
|
let mut iter = self.0.borrow_mut();
|
||||||
|
iter.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IntoValueStream {
|
||||||
|
fn into_value_stream(self) -> ValueStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoValueStream for Vec<Value> {
|
||||||
|
fn into_value_stream(self) -> ValueStream {
|
||||||
|
ValueStream(Rc::new(RefCell::new(self.into_iter())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RowStream(Rc<RefCell<dyn Iterator<Item = Vec<Value>>>>);
|
||||||
|
|
||||||
|
impl RowStream {
|
||||||
|
pub fn into_string(self, headers: Vec<String>) -> String {
|
||||||
|
let val: Vec<Vec<Value>> = self.collect();
|
||||||
|
format!(
|
||||||
|
"[{}]\n[{}]",
|
||||||
|
headers
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ".into()),
|
||||||
|
val.into_iter()
|
||||||
|
.map(|x| {
|
||||||
|
x.into_iter()
|
||||||
|
.map(|x| x.into_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ".into())
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for RowStream {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("ValueStream").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for RowStream {
|
||||||
|
type Item = Vec<Value>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
{
|
||||||
|
let mut iter = self.0.borrow_mut();
|
||||||
|
iter.next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait IntoRowStream {
|
||||||
|
fn into_row_stream(self) -> RowStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoRowStream for Vec<Vec<Value>> {
|
||||||
|
fn into_row_stream(self) -> RowStream {
|
||||||
|
RowStream(Rc::new(RefCell::new(self.into_iter())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Bool {
|
Bool {
|
||||||
|
@ -23,12 +119,12 @@ pub enum Value {
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
List {
|
List {
|
||||||
val: Vec<Value>,
|
val: ValueStream,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
Table {
|
Table {
|
||||||
headers: Vec<String>,
|
headers: Vec<String>,
|
||||||
val: Vec<Vec<Value>>,
|
val: RowStream,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
Block {
|
Block {
|
||||||
|
@ -88,6 +184,19 @@ impl Value {
|
||||||
Value::Block { .. } => Type::Block,
|
Value::Block { .. } => Type::Block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_string(self) -> String {
|
||||||
|
match self {
|
||||||
|
Value::Bool { val, .. } => val.to_string(),
|
||||||
|
Value::Int { val, .. } => val.to_string(),
|
||||||
|
Value::Float { val, .. } => val.to_string(),
|
||||||
|
Value::String { val, .. } => val,
|
||||||
|
Value::List { val, .. } => val.into_string(),
|
||||||
|
Value::Table { headers, val, .. } => val.into_string(headers),
|
||||||
|
Value::Block { val, .. } => format!("<Block {}>", val),
|
||||||
|
Value::Nothing { .. } => format!("<Nothing>"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Value {
|
impl PartialEq for Value {
|
||||||
|
@ -97,62 +206,12 @@ impl PartialEq for Value {
|
||||||
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => lhs == rhs,
|
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => lhs == rhs,
|
||||||
(Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => lhs == rhs,
|
(Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => lhs == rhs,
|
||||||
(Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => lhs == rhs,
|
(Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => lhs == rhs,
|
||||||
(Value::List { val: l1, .. }, Value::List { val: l2, .. }) => l1 == l2,
|
|
||||||
(Value::Block { val: b1, .. }, Value::Block { val: b2, .. }) => b1 == b2,
|
(Value::Block { val: b1, .. }, Value::Block { val: b2, .. }) => b1 == b2,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Value {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Value::Bool { val, .. } => {
|
|
||||||
write!(f, "{}", val)
|
|
||||||
}
|
|
||||||
Value::Int { val, .. } => {
|
|
||||||
write!(f, "{}", val)
|
|
||||||
}
|
|
||||||
Value::Float { val, .. } => {
|
|
||||||
write!(f, "{}", val)
|
|
||||||
}
|
|
||||||
Value::String { val, .. } => write!(f, "{}", val),
|
|
||||||
Value::List { val, .. } => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"[{}]",
|
|
||||||
val.iter()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ".into())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Value::Table { headers, val, .. } => {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"[{}]\n[{}]",
|
|
||||||
headers
|
|
||||||
.iter()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ".into()),
|
|
||||||
val.iter()
|
|
||||||
.map(|x| {
|
|
||||||
x.iter()
|
|
||||||
.map(|x| x.to_string())
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(", ".into())
|
|
||||||
})
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join("\n")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Value::Block { .. } => write!(f, "<block>"),
|
|
||||||
Value::Nothing { .. } => write!(f, ""),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = nu_parser::span(&[self.span(), rhs.span()]);
|
let span = nu_parser::span(&[self.span(), rhs.span()]);
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
match eval_block(&state, &block) {
|
match eval_block(&state, &block) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
println!("{}", value);
|
println!("{}", value.into_string());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let parser_state = parser_state.borrow();
|
let parser_state = parser_state.borrow();
|
||||||
|
@ -94,7 +94,7 @@ fn main() -> std::io::Result<()> {
|
||||||
|
|
||||||
match eval_block(&state, &block) {
|
match eval_block(&state, &block) {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
println!("{}", value);
|
println!("{}", value.into_string());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let parser_state = parser_state.borrow();
|
let parser_state = parser_state.borrow();
|
||||||
|
|
Loading…
Reference in a new issue