mirror of
https://github.com/nushell/nushell
synced 2025-01-01 15:58:55 +00:00
Merge pull request #110 from nushell/better_value_map
Add map and flat_map to value
This commit is contained in:
commit
9a3b0312d2
4 changed files with 78 additions and 105 deletions
|
@ -1,7 +1,7 @@
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EvaluationContext},
|
engine::{Command, EvaluationContext},
|
||||||
Example, IntoValueStream, ShellError, Signature, Span, Type, Value,
|
Example, ShellError, Signature, Span, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
@ -59,40 +59,9 @@ impl Command for SubCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_chars(call: &Call, input: Value) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
fn split_chars(call: &Call, input: Value) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
|
||||||
let name = call.head;
|
let span = call.head;
|
||||||
|
|
||||||
Ok(match input {
|
Ok(input.flat_map(span, move |x| split_chars_helper(&x, span)))
|
||||||
Value::List { vals, span } => Value::List {
|
|
||||||
vals: vals
|
|
||||||
.iter()
|
|
||||||
.flat_map(|x| split_chars_helper(x, name))
|
|
||||||
.collect(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
Value::Stream { stream, span } => Value::Stream {
|
|
||||||
stream: stream
|
|
||||||
.flat_map(move |x| split_chars_helper(&x, name))
|
|
||||||
.into_value_stream(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
v => {
|
|
||||||
let v_span = v.span();
|
|
||||||
if v.as_string().is_ok() {
|
|
||||||
Value::List {
|
|
||||||
vals: split_chars_helper(&v, name),
|
|
||||||
span: v_span,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Value::Error {
|
|
||||||
error: ShellError::PipelineMismatch {
|
|
||||||
expected: Type::String,
|
|
||||||
expected_span: name,
|
|
||||||
origin: v.span(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EvaluationContext},
|
engine::{Command, EvaluationContext},
|
||||||
IntoValueStream, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
@ -51,43 +51,9 @@ fn split_column(
|
||||||
let rest: Vec<Spanned<String>> = call.rest(context, 1)?;
|
let rest: Vec<Spanned<String>> = call.rest(context, 1)?;
|
||||||
let collapse_empty = call.has_flag("collapse-empty");
|
let collapse_empty = call.has_flag("collapse-empty");
|
||||||
|
|
||||||
Ok(match input {
|
Ok(input.map(name_span, move |x| {
|
||||||
Value::List { vals, span } => Value::List {
|
split_column_helper(&x, &separator, &rest, collapse_empty, name_span)
|
||||||
vals: vals
|
}))
|
||||||
.iter()
|
|
||||||
.map(move |x| split_column_helper(x, &separator, &rest, collapse_empty, name_span))
|
|
||||||
.collect(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
Value::Stream { stream, span } => Value::Stream {
|
|
||||||
stream: stream
|
|
||||||
.map(move |x| split_column_helper(&x, &separator, &rest, collapse_empty, name_span))
|
|
||||||
.into_value_stream(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
v => {
|
|
||||||
if v.as_string().is_ok() {
|
|
||||||
Value::List {
|
|
||||||
vals: vec![split_column_helper(
|
|
||||||
&v,
|
|
||||||
&separator,
|
|
||||||
&rest,
|
|
||||||
collapse_empty,
|
|
||||||
name_span,
|
|
||||||
)],
|
|
||||||
span: call.head,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Value::Error {
|
|
||||||
error: ShellError::PipelineMismatch {
|
|
||||||
expected: Type::String,
|
|
||||||
expected_span: call.head,
|
|
||||||
origin: v.span(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_column_helper(
|
fn split_column_helper(
|
||||||
|
|
|
@ -2,7 +2,7 @@ use nu_engine::CallExt;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EvaluationContext},
|
engine::{Command, EvaluationContext},
|
||||||
IntoValueStream, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct SubCommand;
|
pub struct SubCommand;
|
||||||
|
@ -42,38 +42,9 @@ fn split_row(
|
||||||
let name_span = call.head;
|
let name_span = call.head;
|
||||||
let separator: Spanned<String> = call.req(context, 0)?;
|
let separator: Spanned<String> = call.req(context, 0)?;
|
||||||
|
|
||||||
Ok(match input {
|
Ok(input.flat_map(name_span, move |x| {
|
||||||
Value::List { vals, span } => Value::List {
|
split_row_helper(&x, &separator, name_span)
|
||||||
vals: vals
|
}))
|
||||||
.iter()
|
|
||||||
.flat_map(move |x| split_row_helper(x, &separator, name_span))
|
|
||||||
.collect(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
Value::Stream { stream, span } => Value::Stream {
|
|
||||||
stream: stream
|
|
||||||
.flat_map(move |x| split_row_helper(&x, &separator, name_span))
|
|
||||||
.into_value_stream(),
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
v => {
|
|
||||||
let v_span = v.span();
|
|
||||||
if v.as_string().is_ok() {
|
|
||||||
Value::List {
|
|
||||||
vals: split_row_helper(&v, &separator, name_span),
|
|
||||||
span: v_span,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Value::Error {
|
|
||||||
error: ShellError::PipelineMismatch {
|
|
||||||
expected: Type::String,
|
|
||||||
expected_span: call.head,
|
|
||||||
origin: v.span(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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> {
|
||||||
|
|
|
@ -364,6 +364,73 @@ impl Value {
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map<F>(self, span: Span, mut f: F) -> Value
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
F: FnMut(Self) -> Value + 'static,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Value::List { vals, .. } => Value::List {
|
||||||
|
vals: vals.into_iter().map(f).collect(),
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
Value::Stream { stream, .. } => Value::Stream {
|
||||||
|
stream: stream.map(f).into_value_stream(),
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
v => {
|
||||||
|
if v.as_string().is_ok() {
|
||||||
|
Value::List {
|
||||||
|
vals: vec![f(v)],
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::Error {
|
||||||
|
error: ShellError::PipelineMismatch {
|
||||||
|
expected: Type::String,
|
||||||
|
expected_span: span,
|
||||||
|
origin: v.span(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flat_map<U, F>(self, span: Span, mut f: F) -> Value
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
U: IntoIterator<Item = Value>,
|
||||||
|
F: FnMut(Self) -> U + 'static,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
Value::List { vals, .. } => Value::List {
|
||||||
|
vals: vals.into_iter().map(f).flatten().collect(),
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
Value::Stream { stream, .. } => Value::Stream {
|
||||||
|
stream: stream.map(f).flatten().into_value_stream(),
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
v => {
|
||||||
|
if v.as_string().is_ok() {
|
||||||
|
Value::List {
|
||||||
|
vals: f(v).into_iter().collect(),
|
||||||
|
span,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value::Error {
|
||||||
|
error: ShellError::PipelineMismatch {
|
||||||
|
expected: Type::String,
|
||||||
|
expected_span: span,
|
||||||
|
origin: v.span(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Value {
|
impl PartialEq for Value {
|
||||||
|
|
Loading…
Reference in a new issue