Merge pull request #244 from nushell/more_helpers

Add more helper functions
This commit is contained in:
JT 2021-10-20 19:11:58 +13:00 committed by GitHub
commit 1c52919103
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 98 additions and 121 deletions

1
Cargo.lock generated
View File

@ -596,6 +596,7 @@ dependencies = [
name = "nu-engine"
version = "0.1.0"
dependencies = [
"chrono",
"itertools",
"nu-parser",
"nu-path",

View File

@ -55,26 +55,17 @@ impl Command for SubCommand {
Example {
description: "Convert string to integer",
example: "'2' | into int",
result: Some(Value::Int {
val: 2,
span: Span::unknown(),
}),
result: Some(Value::test_int(2)),
},
Example {
description: "Convert decimal to integer",
example: "5.9 | into int",
result: Some(Value::Int {
val: 5,
span: Span::unknown(),
}),
result: Some(Value::test_int(5)),
},
Example {
description: "Convert decimal string to integer",
example: "'5.9' | into int",
result: Some(Value::Int {
val: 5,
span: Span::unknown(),
}),
result: Some(Value::test_int(5)),
},
Example {
description: "Convert file size to integer",
@ -88,18 +79,9 @@ impl Command for SubCommand {
description: "Convert bool to integer",
example: "[$false, $true] | into int",
result: Some(Value::Stream {
stream: vec![
Value::Int {
val: 0,
span: Span::unknown(),
},
Value::Int {
val: 1,
span: Span::unknown(),
},
]
.into_iter()
.into_value_stream(),
stream: vec![Value::test_int(0), Value::test_int(1)]
.into_iter()
.into_value_stream(),
span: Span::unknown(),
}),
},

View File

@ -34,7 +34,10 @@ impl Command for Git {
Ok(val) => {
let result = val.stdout;
Ok(Value::string(&String::from_utf8_lossy(&result), call.head))
Ok(Value::String {
val: String::from_utf8_lossy(&result).to_string(),
span: call.head,
})
}
Err(_err) => {
// FIXME: Move this to an external signature and add better error handling

View File

@ -49,7 +49,10 @@ impl Command for GitCheckout {
Ok(val) => {
let result = val.stdout;
Ok(Value::string(&String::from_utf8_lossy(&result), call.head))
Ok(Value::String {
val: String::from_utf8_lossy(&result).to_string(),
span: call.head,
})
}
Err(_err) => {
// FIXME: Move this to an external signature and add better error handling

View File

@ -42,7 +42,7 @@ impl Command for Lines {
let iter = lines.into_iter().filter_map(move |s| {
if !s.is_empty() {
Some(Value::String { val: s, span })
Some(Value::string(s, span))
} else {
None
}

View File

@ -25,26 +25,11 @@ impl Command for SubCommand {
example: "'hello' | split chars",
result: Some(Value::List {
vals: vec![
Value::String {
val: "h".into(),
span: Span::unknown(),
},
Value::String {
val: "e".into(),
span: Span::unknown(),
},
Value::String {
val: "l".into(),
span: Span::unknown(),
},
Value::String {
val: "l".into(),
span: Span::unknown(),
},
Value::String {
val: "o".into(),
span: Span::unknown(),
},
Value::test_string("h"),
Value::test_string("e"),
Value::test_string("l"),
Value::test_string("l"),
Value::test_string("o"),
],
span: Span::unknown(),
}),
@ -74,10 +59,7 @@ fn split_chars_helper(v: &Value, name: Span) -> Vec<Value> {
s.chars()
.collect::<Vec<_>>()
.into_iter()
.map(move |x| Value::String {
val: x.to_string(),
span: v_span,
})
.map(move |x| Value::string(x, v_span))
.collect()
} else {
vec![Value::Error {

View File

@ -86,18 +86,12 @@ fn split_column_helper(
for (&k, v) in split_result.iter().zip(&gen_columns) {
cols.push(v.to_string());
vals.push(Value::String {
val: k.into(),
span: head,
});
vals.push(Value::string(k, head));
}
} else {
for (&k, v) in split_result.iter().zip(&positional) {
cols.push(v.into());
vals.push(Value::String {
val: k.into(),
span: head,
})
vals.push(Value::string(k, head));
}
}
Value::List {

View File

@ -55,10 +55,7 @@ fn split_row_helper(v: &Value, separator: &Spanned<String>, name: Span) -> Vec<V
s.split(&splitter)
.filter_map(|s| {
if s.trim() != "" {
Some(Value::String {
val: s.into(),
span: v_span,
})
Some(Value::string(s, v_span))
} else {
None
}

View File

@ -8,3 +8,4 @@ nu-parser = { path = "../nu-parser" }
nu-protocol = { path = "../nu-protocol" }
nu-path = { path = "../nu-path" }
itertools = "0.10.1"
chrono = { version="0.4.19", features=["serde"] }

View File

@ -1,5 +1,6 @@
// use std::path::PathBuf;
use chrono::{DateTime, FixedOffset};
// use nu_path::expand_path;
use nu_protocol::ast::{CellPath, PathMember};
use nu_protocol::ShellError;
@ -134,27 +135,26 @@ impl FromValue for Spanned<bool> {
}
}
// impl FromValue for DateTime<FixedOffset> {
// fn from_value(v: &Value) -> Result<Self, ShellError> {
// match v {
// Value {
// value: UntaggedValue::Primitive(Primitive::Date(d)),
// ..
// } => Ok(*d),
// Value {
// value: UntaggedValue::Row(_),
// ..
// } => {
// let mut shell_error = ShellError::type_error("date", v.spanned_type_name());
// shell_error.notes.push(
// "Note: you can access columns using dot. eg) $it.column or (ls).column".into(),
// );
// Err(shell_error)
// }
// v => Err(ShellError::type_error("date", v.spanned_type_name())),
// }
// }
// }
impl FromValue for DateTime<FixedOffset> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Date { val, .. } => Ok(*val),
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
}
}
}
impl FromValue for Spanned<DateTime<FixedOffset>> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Date { val, span } => Ok(Spanned {
item: *val,
span: *span,
}),
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
}
}
}
impl FromValue for Range {
fn from_value(v: &Value) -> Result<Self, ShellError> {
@ -177,31 +177,15 @@ impl FromValue for Spanned<Range> {
}
}
// impl FromValue for Vec<u8> {
// fn from_value(v: &Value) -> Result<Self, ShellError> {
// match v {
// Value {
// value: UntaggedValue::Primitive(Primitive::Binary(b)),
// ..
// } => Ok(b.clone()),
// Value {
// value: UntaggedValue::Primitive(Primitive::String(s)),
// ..
// } => Ok(s.bytes().collect()),
// Value {
// value: UntaggedValue::Row(_),
// ..
// } => {
// let mut shell_error = ShellError::type_error("binary data", v.spanned_type_name());
// shell_error.notes.push(
// "Note: you can access columns using dot. eg) $it.column or (ls).column".into(),
// );
// Err(shell_error)
// }
// v => Err(ShellError::type_error("binary data", v.spanned_type_name())),
// }
// }
// }
impl FromValue for Vec<u8> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
match v {
Value::Binary { val, .. } => Ok(val.clone()),
Value::String { val, .. } => Ok(val.bytes().collect()),
v => Err(ShellError::CantConvert("binary data".into(), v.span()?)),
}
}
}
// impl FromValue for Dictionary {
// fn from_value(v: &Value) -> Result<Self, ShellError> {

View File

@ -19,6 +19,10 @@ pub enum ShellError {
rhs_span: Span,
},
#[error("Operator overflow.")]
#[diagnostic(code(nu::shell::operator_overflow), url(docsrs))]
OperatorOverflow(String, #[label = "{0}"] Span),
#[error("Pipeline mismatch.")]
#[diagnostic(code(nu::shell::pipeline_mismatch), url(docsrs))]
PipelineMismatch {

View File

@ -363,13 +363,6 @@ impl Value {
Ok(current)
}
pub fn string(s: &str, span: Span) -> Value {
Value::String {
val: s.into(),
span,
}
}
pub fn is_true(&self) -> bool {
matches!(self, Value::Bool { val: true, .. })
}
@ -438,6 +431,33 @@ impl Value {
},
}
}
pub fn string(val: impl Into<String>, span: Span) -> Value {
Value::String {
val: val.into(),
span,
}
}
pub fn int(val: i64, span: Span) -> Value {
Value::Int { val, span }
}
// Only use these for test data. Span::unknown() should not be used in user data
pub fn test_string(s: impl Into<String>) -> Value {
Value::String {
val: s.into(),
span: Span::unknown(),
}
}
// Only use these for test data. Span::unknown() should not be used in user data
pub fn test_int(val: i64) -> Value {
Value::Int {
val,
span: Span::unknown(),
}
}
}
impl PartialOrd for Value {
@ -528,10 +548,16 @@ impl Value {
let span = span(&[self.span()?, rhs.span()?]);
match (self, rhs) {
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int {
val: lhs + rhs,
span,
}),
(Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => {
if let Some(val) = lhs.checked_add(*rhs) {
Ok(Value::Int { val, span })
} else {
Err(ShellError::OperatorOverflow(
"add operation overflowed".into(),
span,
))
}
}
(Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float {
val: *lhs as f64 + *rhs,
span,