forked from extern/nushell
Merge pull request #244 from nushell/more_helpers
Add more helper functions
This commit is contained in:
commit
1c52919103
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -596,6 +596,7 @@ dependencies = [
|
||||
name = "nu-engine"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"itertools",
|
||||
"nu-parser",
|
||||
"nu-path",
|
||||
|
@ -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,16 +79,7 @@ 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(),
|
||||
},
|
||||
]
|
||||
stream: vec![Value::test_int(0), Value::test_int(1)]
|
||||
.into_iter()
|
||||
.into_value_stream(),
|
||||
span: Span::unknown(),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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"] }
|
@ -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> {
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
(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,
|
||||
|
Loading…
Reference in New Issue
Block a user