mirror of
https://github.com/nushell/nushell.git
synced 2025-08-19 10:03:24 +02:00
WIP
This commit is contained in:
@@ -59,10 +59,6 @@ pub enum Value {
|
||||
vals: Vec<Value>,
|
||||
span: Span,
|
||||
},
|
||||
Stream {
|
||||
stream: ValueStream,
|
||||
span: Span,
|
||||
},
|
||||
List {
|
||||
vals: Vec<Value>,
|
||||
span: Span,
|
||||
@@ -110,7 +106,6 @@ impl Value {
|
||||
Value::Record { span, .. } => Ok(*span),
|
||||
Value::List { span, .. } => Ok(*span),
|
||||
Value::Block { span, .. } => Ok(*span),
|
||||
Value::Stream { span, .. } => Ok(*span),
|
||||
Value::Nothing { span, .. } => Ok(*span),
|
||||
Value::Binary { span, .. } => Ok(*span),
|
||||
Value::CellPath { span, .. } => Ok(*span),
|
||||
@@ -129,7 +124,6 @@ impl Value {
|
||||
Value::Range { span, .. } => *span = new_span,
|
||||
Value::String { span, .. } => *span = new_span,
|
||||
Value::Record { span, .. } => *span = new_span,
|
||||
Value::Stream { span, .. } => *span = new_span,
|
||||
Value::List { span, .. } => *span = new_span,
|
||||
Value::Block { span, .. } => *span = new_span,
|
||||
Value::Nothing { span, .. } => *span = new_span,
|
||||
@@ -158,7 +152,6 @@ impl Value {
|
||||
Value::List { .. } => Type::List(Box::new(Type::Unknown)), // FIXME
|
||||
Value::Nothing { .. } => Type::Nothing,
|
||||
Value::Block { .. } => Type::Block,
|
||||
Value::Stream { .. } => Type::ValueStream,
|
||||
Value::Error { .. } => Type::Error,
|
||||
Value::Binary { .. } => Type::Binary,
|
||||
Value::CellPath { .. } => Type::CellPath,
|
||||
@@ -186,7 +179,6 @@ impl Value {
|
||||
Err(error) => format!("{:?}", error),
|
||||
},
|
||||
Value::String { val, .. } => val,
|
||||
Value::Stream { stream, .. } => stream.into_string(),
|
||||
Value::List { vals: val, .. } => format!(
|
||||
"[{}]",
|
||||
val.into_iter()
|
||||
@@ -228,7 +220,6 @@ impl Value {
|
||||
}
|
||||
},
|
||||
Value::String { val, .. } => val,
|
||||
Value::Stream { stream, .. } => stream.collect_string(),
|
||||
Value::List { vals: val, .. } => val
|
||||
.into_iter()
|
||||
.map(|x| x.collect_string())
|
||||
@@ -274,13 +265,6 @@ impl Value {
|
||||
return Err(ShellError::AccessBeyondEnd(val.len(), *origin_span));
|
||||
}
|
||||
}
|
||||
Value::Stream { stream, .. } => {
|
||||
if let Some(item) = stream.nth(*count) {
|
||||
current = item;
|
||||
} else {
|
||||
return Err(ShellError::AccessBeyondEndOfStream(*origin_span));
|
||||
}
|
||||
}
|
||||
x => {
|
||||
return Err(ShellError::IncompatiblePathAccess(
|
||||
format!("{}", x.get_type()),
|
||||
@@ -329,27 +313,6 @@ impl Value {
|
||||
span: *span,
|
||||
};
|
||||
}
|
||||
Value::Stream { stream, span } => {
|
||||
let mut output = vec![];
|
||||
for val in stream {
|
||||
output.push(val.clone().follow_cell_path(&[PathMember::String {
|
||||
val: column_name.clone(),
|
||||
span: *origin_span,
|
||||
}])?);
|
||||
// if let Value::Record { cols, vals, .. } = val {
|
||||
// for col in cols.iter().enumerate() {
|
||||
// if col.1 == column_name {
|
||||
// output.push(vals[col.0].clone());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
current = Value::List {
|
||||
vals: output,
|
||||
span: *span,
|
||||
};
|
||||
}
|
||||
x => {
|
||||
return Err(ShellError::IncompatiblePathAccess(
|
||||
format!("{}", x.get_type()),
|
||||
@@ -374,64 +337,6 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map<F>(self, span: Span, mut f: F) -> Result<Value, ShellError>
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(Self) -> Value + 'static,
|
||||
{
|
||||
match self {
|
||||
Value::List { vals, .. } => Ok(Value::Stream {
|
||||
stream: vals.into_iter().map(f).into_value_stream(),
|
||||
span,
|
||||
}),
|
||||
Value::Stream { stream, .. } => Ok(Value::Stream {
|
||||
stream: stream.map(f).into_value_stream(),
|
||||
span,
|
||||
}),
|
||||
Value::Range { val, .. } => Ok(Value::Stream {
|
||||
stream: val.into_range_iter()?.map(f).into_value_stream(),
|
||||
span,
|
||||
}),
|
||||
v => {
|
||||
let output = f(v);
|
||||
match output {
|
||||
Value::Error { error } => Err(error),
|
||||
v => Ok(v),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn flat_map<U, F>(self, span: Span, mut f: F) -> Value
|
||||
where
|
||||
Self: Sized,
|
||||
U: IntoIterator<Item = Value>,
|
||||
<U as IntoIterator>::IntoIter: 'static,
|
||||
F: FnMut(Self) -> U + 'static,
|
||||
{
|
||||
match self {
|
||||
Value::List { vals, .. } => Value::Stream {
|
||||
stream: vals.into_iter().map(f).flatten().into_value_stream(),
|
||||
span,
|
||||
},
|
||||
Value::Stream { stream, .. } => Value::Stream {
|
||||
stream: stream.map(f).flatten().into_value_stream(),
|
||||
span,
|
||||
},
|
||||
Value::Range { val, .. } => match val.into_range_iter() {
|
||||
Ok(iter) => Value::Stream {
|
||||
stream: iter.map(f).flatten().into_value_stream(),
|
||||
span,
|
||||
},
|
||||
Err(error) => Value::Error { error },
|
||||
},
|
||||
v => Value::Stream {
|
||||
stream: f(v).into_iter().into_value_stream(),
|
||||
span,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn string(val: impl Into<String>, span: Span) -> Value {
|
||||
Value::String {
|
||||
val: val.into(),
|
||||
@@ -460,6 +365,12 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Value {
|
||||
fn default() -> Self {
|
||||
Value::nothing()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Value {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
// Compare two floating point numbers. The decision interval for equality is dynamically
|
||||
@@ -511,24 +422,6 @@ impl PartialOrd for Value {
|
||||
..
|
||||
},
|
||||
) if lhs_headers == rhs_headers && lhs == rhs => Some(Ordering::Equal),
|
||||
(Value::Stream { stream: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
|
||||
lhs.clone().partial_cmp(rhs.clone())
|
||||
}
|
||||
(Value::Stream { stream: lhs, .. }, Value::String { val: rhs, .. }) => {
|
||||
lhs.clone().collect_string().partial_cmp(rhs)
|
||||
}
|
||||
(Value::String { val: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
|
||||
lhs.partial_cmp(&rhs.clone().collect_string())
|
||||
}
|
||||
// NOTE: This may look a bit strange, but a `Stream` is still just a `List`, it just
|
||||
// happens to be in an iterator form instead of a concrete form. The contained values
|
||||
// can be compared.
|
||||
(Value::Stream { stream: lhs, .. }, Value::List { vals: rhs, .. }) => {
|
||||
lhs.clone().collect::<Vec<Value>>().partial_cmp(rhs)
|
||||
}
|
||||
(Value::List { vals: lhs, .. }, Value::Stream { stream: rhs, .. }) => {
|
||||
lhs.partial_cmp(&rhs.clone().collect::<Vec<Value>>())
|
||||
}
|
||||
(Value::Binary { val: lhs, .. }, Value::Binary { val: rhs, .. }) => {
|
||||
lhs.partial_cmp(rhs)
|
||||
}
|
||||
@@ -852,10 +745,6 @@ impl Value {
|
||||
val: rhs.contains(lhs),
|
||||
span,
|
||||
}),
|
||||
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
|
||||
val: rhs.clone().any(|x| lhs == &x),
|
||||
span,
|
||||
}),
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
@@ -886,10 +775,6 @@ impl Value {
|
||||
val: !rhs.contains(lhs),
|
||||
span,
|
||||
}),
|
||||
(lhs, Value::Stream { stream: rhs, .. }) => Ok(Value::Bool {
|
||||
val: rhs.clone().all(|x| lhs != &x),
|
||||
span,
|
||||
}),
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
|
@@ -1,10 +1,7 @@
|
||||
use crate::*;
|
||||
use std::{cell::RefCell, fmt::Debug, rc::Rc};
|
||||
use std::fmt::Debug;
|
||||
|
||||
use serde::{ser::SerializeSeq, Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ValueStream(pub Rc<RefCell<dyn Iterator<Item = Value>>>);
|
||||
pub struct ValueStream(pub Box<dyn Iterator<Item = Value> + Send + 'static>);
|
||||
|
||||
impl ValueStream {
|
||||
pub fn into_string(self) -> String {
|
||||
@@ -22,8 +19,8 @@ impl ValueStream {
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
pub fn from_stream(input: impl Iterator<Item = Value> + 'static) -> ValueStream {
|
||||
ValueStream(Rc::new(RefCell::new(input)))
|
||||
pub fn from_stream(input: impl Iterator<Item = Value> + Send + 'static) -> ValueStream {
|
||||
ValueStream(Box::new(input))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,66 +35,66 @@ impl Iterator for ValueStream {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
{
|
||||
self.0.borrow_mut().next()
|
||||
self.0.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for ValueStream {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(None)?;
|
||||
// impl Serialize for ValueStream {
|
||||
// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
// where
|
||||
// S: serde::Serializer,
|
||||
// {
|
||||
// let mut seq = serializer.serialize_seq(None)?;
|
||||
|
||||
for element in self.0.borrow_mut().into_iter() {
|
||||
seq.serialize_element(&element)?;
|
||||
}
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
// for element in self.0.borrow_mut().into_iter() {
|
||||
// seq.serialize_element(&element)?;
|
||||
// }
|
||||
// seq.end()
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<'de> Deserialize<'de> for ValueStream {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(MySeqVisitor)
|
||||
}
|
||||
}
|
||||
// impl<'de> Deserialize<'de> for ValueStream {
|
||||
// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
// where
|
||||
// D: serde::Deserializer<'de>,
|
||||
// {
|
||||
// deserializer.deserialize_seq(MySeqVisitor)
|
||||
// }
|
||||
// }
|
||||
|
||||
struct MySeqVisitor;
|
||||
// struct MySeqVisitor;
|
||||
|
||||
impl<'a> serde::de::Visitor<'a> for MySeqVisitor {
|
||||
type Value = ValueStream;
|
||||
// impl<'a> serde::de::Visitor<'a> for MySeqVisitor {
|
||||
// type Value = ValueStream;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("a value stream")
|
||||
}
|
||||
// fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
// formatter.write_str("a value stream")
|
||||
// }
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: serde::de::SeqAccess<'a>,
|
||||
{
|
||||
let mut output: Vec<Value> = vec![];
|
||||
// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
// where
|
||||
// A: serde::de::SeqAccess<'a>,
|
||||
// {
|
||||
// let mut output: Vec<Value> = vec![];
|
||||
|
||||
while let Some(value) = seq.next_element()? {
|
||||
output.push(value);
|
||||
}
|
||||
// while let Some(value) = seq.next_element()? {
|
||||
// output.push(value);
|
||||
// }
|
||||
|
||||
Ok(ValueStream(Rc::new(RefCell::new(output.into_iter()))))
|
||||
}
|
||||
}
|
||||
// Ok(ValueStream(Rc::new(RefCell::new(output.into_iter()))))
|
||||
// }
|
||||
// }
|
||||
|
||||
pub trait IntoValueStream {
|
||||
fn into_value_stream(self) -> ValueStream;
|
||||
}
|
||||
// pub trait IntoValueStream {
|
||||
// fn into_value_stream(self) -> ValueStream;
|
||||
// }
|
||||
|
||||
impl<T> IntoValueStream for T
|
||||
where
|
||||
T: Iterator<Item = Value> + 'static,
|
||||
{
|
||||
fn into_value_stream(self) -> ValueStream {
|
||||
ValueStream::from_stream(self)
|
||||
}
|
||||
}
|
||||
// impl<T> IntoValueStream for T
|
||||
// where
|
||||
// T: Iterator<Item = Value> + 'static,
|
||||
// {
|
||||
// fn into_value_stream(self) -> ValueStream {
|
||||
// ValueStream::from_stream(self)
|
||||
// }
|
||||
// }
|
||||
|
Reference in New Issue
Block a user