mirror of
https://github.com/nushell/nushell
synced 2024-12-26 04:53:09 +00:00
Remove old ValueExt
This commit is contained in:
parent
9f702fe01a
commit
fd6ee03391
17 changed files with 18 additions and 529 deletions
|
@ -104,7 +104,7 @@ impl ValueExt for Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_data_by_member(value: &Value, name: &PathMember) -> Result<Value, ShellError> {
|
pub fn get_data_by_member(value: &Value, name: &PathMember) -> Result<Value, ShellError> {
|
||||||
match &value.value {
|
match &value.value {
|
||||||
// If the value is a row, the member is a column name
|
// If the value is a row, the member is a column name
|
||||||
UntaggedValue::Row(o) => match &name.unspanned {
|
UntaggedValue::Row(o) => match &name.unspanned {
|
||||||
|
@ -453,7 +453,7 @@ pub(crate) fn get_data_by_index(value: &Value, idx: Spanned<usize>) -> Option<Va
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_data_by_key(value: &Value, name: Spanned<&str>) -> Option<Value> {
|
pub fn get_data_by_key(value: &Value, name: Spanned<&str>) -> Option<Value> {
|
||||||
match &value.value {
|
match &value.value {
|
||||||
UntaggedValue::Row(o) => o.get_data_by_key(name),
|
UntaggedValue::Row(o) => o.get_data_by_key(name),
|
||||||
UntaggedValue::Table(l) => {
|
UntaggedValue::Table(l) => {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct DefaultArgs {
|
struct DefaultArgs {
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::context::CommandRegistry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{CallInfo, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{CallInfo, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
pub struct Edit;
|
pub struct Edit;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::{SpannedItem, Tagged};
|
use nu_source::{SpannedItem, Tagged};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
pub struct EvaluateBy;
|
pub struct EvaluateBy;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::property_get::get_data_by_column_path;
|
|
||||||
use crate::data::base::shape::Shapes;
|
use crate::data::base::shape::Shapes;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use futures_util::pin_mut;
|
use futures_util::pin_mut;
|
||||||
|
@ -10,6 +9,7 @@ use nu_protocol::{
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
use nu_source::{span_for_spanned_list, PrettyDebug};
|
use nu_source::{span_for_spanned_list, PrettyDebug};
|
||||||
|
use nu_value_ext::get_data_by_column_path;
|
||||||
|
|
||||||
pub struct Get;
|
pub struct Get;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
pub struct GroupBy;
|
pub struct GroupBy;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::commands::PerItemCommand;
|
use crate::commands::PerItemCommand;
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::data::command_dict;
|
use crate::data::command_dict;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
|
@ -8,6 +7,7 @@ use nu_protocol::{
|
||||||
TaggedDictBuilder, UntaggedValue, Value,
|
TaggedDictBuilder, UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::SpannedItem;
|
use nu_source::SpannedItem;
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
pub struct Help;
|
pub struct Help;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::context::CommandRegistry;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{CallInfo, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{CallInfo, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
|
|
||||||
pub struct Insert;
|
pub struct Insert;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value};
|
||||||
use nu_source::{SpannedItem, Tagged};
|
use nu_source::{SpannedItem, Tagged};
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
pub struct Pivot;
|
pub struct Pivot;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
pub struct SortBy;
|
pub struct SortBy;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::commands::WholeStreamCommand;
|
use crate::commands::WholeStreamCommand;
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::data::TaggedListBuilder;
|
use crate::data::TaggedListBuilder;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use chrono::{DateTime, NaiveDate, Utc};
|
use chrono::{DateTime, NaiveDate, Utc};
|
||||||
|
@ -8,6 +7,7 @@ use nu_protocol::{
|
||||||
Primitive, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
Primitive, ReturnSuccess, Signature, SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
pub struct TSortBy;
|
pub struct TSortBy;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::data::base::property_get::get_data_by_key;
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use csv::WriterBuilder;
|
use csv::WriterBuilder;
|
||||||
use indexmap::{indexset, IndexSet};
|
use indexmap::{indexset, IndexSet};
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ReturnSuccess, UntaggedValue, Value};
|
||||||
use nu_source::Spanned;
|
use nu_source::Spanned;
|
||||||
|
use nu_value_ext::get_data_by_key;
|
||||||
|
|
||||||
fn from_value_to_delimited_string(
|
fn from_value_to_delimited_string(
|
||||||
tagged_value: &Value,
|
tagged_value: &Value,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
pub(crate) mod property_get;
|
|
||||||
pub(crate) mod shape;
|
pub(crate) mod shape;
|
||||||
|
|
||||||
use crate::context::CommandRegistry;
|
use crate::context::CommandRegistry;
|
||||||
use crate::data::base::property_get::ValueExt;
|
|
||||||
use crate::evaluate::evaluate_baseline_expr;
|
use crate::evaluate::evaluate_baseline_expr;
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
@ -15,6 +13,7 @@ use nu_protocol::{
|
||||||
UntaggedValue, Value,
|
UntaggedValue, Value,
|
||||||
};
|
};
|
||||||
use nu_source::{Tag, Text};
|
use nu_source::{Tag, Text};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use query_interface::{interfaces, vtable_for, ObjectHash};
|
use query_interface::{interfaces, vtable_for, ObjectHash};
|
||||||
|
@ -196,11 +195,11 @@ fn coerce_compare_primitive(
|
||||||
}
|
}
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::data::base::property_get::{as_column_path, ValueExt};
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ColumnPath as ColumnPathValue, PathMember, UntaggedValue, Value};
|
use nu_protocol::{ColumnPath as ColumnPathValue, PathMember, UntaggedValue, Value};
|
||||||
use nu_source::*;
|
use nu_source::*;
|
||||||
|
use nu_value_ext::{as_column_path, ValueExt};
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
|
|
||||||
fn string(input: impl Into<String>) -> Value {
|
fn string(input: impl Into<String>) -> Value {
|
||||||
|
|
|
@ -1,514 +0,0 @@
|
||||||
use crate::prelude::*;
|
|
||||||
use nu_errors::{ExpectedRange, ShellError};
|
|
||||||
use nu_protocol::{
|
|
||||||
ColumnPath, PathMember, Primitive, ShellTypeName, SpannedTypeName, UnspannedPathMember,
|
|
||||||
UntaggedValue, Value,
|
|
||||||
};
|
|
||||||
use nu_source::{Spanned, SpannedItem, Tagged};
|
|
||||||
|
|
||||||
pub trait ValueExt {
|
|
||||||
fn into_parts(self) -> (UntaggedValue, Tag);
|
|
||||||
fn get_data(&self, desc: &String) -> MaybeOwned<'_, Value>;
|
|
||||||
fn get_data_by_key(&self, name: Spanned<&str>) -> Option<Value>;
|
|
||||||
fn get_data_by_member(&self, name: &PathMember) -> Result<Value, ShellError>;
|
|
||||||
fn get_data_by_column_path(
|
|
||||||
&self,
|
|
||||||
path: &ColumnPath,
|
|
||||||
callback: Box<dyn FnOnce((&Value, &PathMember, ShellError)) -> ShellError>,
|
|
||||||
) -> Result<Value, ShellError>;
|
|
||||||
fn insert_data_at_path(&self, path: &str, new_value: Value) -> Option<Value>;
|
|
||||||
fn insert_data_at_member(
|
|
||||||
&mut self,
|
|
||||||
member: &PathMember,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<(), ShellError>;
|
|
||||||
fn insert_data_at_column_path(
|
|
||||||
&self,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<Value, ShellError>;
|
|
||||||
fn replace_data_at_column_path(
|
|
||||||
&self,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
replaced_value: Value,
|
|
||||||
) -> Option<Value>;
|
|
||||||
fn as_column_path(&self) -> Result<Tagged<ColumnPath>, ShellError>;
|
|
||||||
fn as_path_member(&self) -> Result<PathMember, ShellError>;
|
|
||||||
fn as_string(&self) -> Result<String, ShellError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ValueExt for Value {
|
|
||||||
fn into_parts(self) -> (UntaggedValue, Tag) {
|
|
||||||
(self.value, self.tag)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data(&self, desc: &String) -> MaybeOwned<'_, Value> {
|
|
||||||
get_data(self, desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data_by_key(&self, name: Spanned<&str>) -> Option<Value> {
|
|
||||||
get_data_by_key(self, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data_by_member(&self, name: &PathMember) -> Result<Value, ShellError> {
|
|
||||||
get_data_by_member(self, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_data_by_column_path(
|
|
||||||
&self,
|
|
||||||
path: &ColumnPath,
|
|
||||||
callback: Box<dyn FnOnce((&Value, &PathMember, ShellError)) -> ShellError>,
|
|
||||||
) -> Result<Value, ShellError> {
|
|
||||||
get_data_by_column_path(self, path, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_data_at_path(&self, path: &str, new_value: Value) -> Option<Value> {
|
|
||||||
insert_data_at_path(self, path, new_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_data_at_member(
|
|
||||||
&mut self,
|
|
||||||
member: &PathMember,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<(), ShellError> {
|
|
||||||
insert_data_at_member(self, member, new_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_data_at_column_path(
|
|
||||||
&self,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<Value, ShellError> {
|
|
||||||
insert_data_at_column_path(self, split_path, new_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_data_at_column_path(
|
|
||||||
&self,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
replaced_value: Value,
|
|
||||||
) -> Option<Value> {
|
|
||||||
replace_data_at_column_path(self, split_path, replaced_value)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_column_path(&self) -> Result<Tagged<ColumnPath>, ShellError> {
|
|
||||||
as_column_path(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_path_member(&self) -> Result<PathMember, ShellError> {
|
|
||||||
as_path_member(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_string(&self) -> Result<String, ShellError> {
|
|
||||||
as_string(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_data_by_member(value: &Value, name: &PathMember) -> Result<Value, ShellError> {
|
|
||||||
match &value.value {
|
|
||||||
// If the value is a row, the member is a column name
|
|
||||||
UntaggedValue::Row(o) => match &name.unspanned {
|
|
||||||
// If the member is a string, get the data
|
|
||||||
UnspannedPathMember::String(string) => o
|
|
||||||
.get_data_by_key(string[..].spanned(name.span))
|
|
||||||
.ok_or_else(|| {
|
|
||||||
ShellError::missing_property(
|
|
||||||
"row".spanned(value.tag.span),
|
|
||||||
string.spanned(name.span),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
|
|
||||||
// If the member is a number, it's an error
|
|
||||||
UnspannedPathMember::Int(_) => Err(ShellError::invalid_integer_index(
|
|
||||||
"row".spanned(value.tag.span),
|
|
||||||
name.span,
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
|
|
||||||
// If the value is a table
|
|
||||||
UntaggedValue::Table(l) => {
|
|
||||||
match &name.unspanned {
|
|
||||||
// If the member is a string, map over the member
|
|
||||||
UnspannedPathMember::String(string) => {
|
|
||||||
let mut out = vec![];
|
|
||||||
|
|
||||||
for item in l {
|
|
||||||
if let Value {
|
|
||||||
value: UntaggedValue::Row(o),
|
|
||||||
..
|
|
||||||
} = item
|
|
||||||
{
|
|
||||||
if let Some(v) = o.get_data_by_key(string[..].spanned(name.span)) {
|
|
||||||
out.push(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if out.is_empty() {
|
|
||||||
Err(ShellError::missing_property(
|
|
||||||
"table".spanned(value.tag.span),
|
|
||||||
string.spanned(name.span),
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(UntaggedValue::Table(out)
|
|
||||||
.into_value(Tag::new(value.anchor(), name.span)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnspannedPathMember::Int(int) => {
|
|
||||||
let index = int.to_usize().ok_or_else(|| {
|
|
||||||
ShellError::range_error(
|
|
||||||
ExpectedRange::Usize,
|
|
||||||
&"massive integer".spanned(name.span),
|
|
||||||
"indexing",
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
match get_data_by_index(value, index.spanned(value.tag.span)) {
|
|
||||||
Some(v) => Ok(v.clone()),
|
|
||||||
None => Err(ShellError::range_error(
|
|
||||||
0..(l.len()),
|
|
||||||
&int.spanned(name.span),
|
|
||||||
"indexing",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
other => Err(ShellError::type_error(
|
|
||||||
"row or table",
|
|
||||||
other.type_name().spanned(value.tag.span),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_data_by_column_path(
|
|
||||||
value: &Value,
|
|
||||||
path: &ColumnPath,
|
|
||||||
callback: Box<dyn FnOnce((&Value, &PathMember, ShellError)) -> ShellError>,
|
|
||||||
) -> Result<Value, ShellError> {
|
|
||||||
let mut current = value.clone();
|
|
||||||
|
|
||||||
for p in path.iter() {
|
|
||||||
let value = get_data_by_member(¤t, p);
|
|
||||||
|
|
||||||
match value {
|
|
||||||
Ok(v) => current = v.clone(),
|
|
||||||
Err(e) => return Err(callback((¤t.clone(), &p.clone(), e))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(current)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_data_at_path(value: &Value, path: &str, new_value: Value) -> Option<Value> {
|
|
||||||
let mut new_obj = value.clone();
|
|
||||||
|
|
||||||
let split_path: Vec<_> = path.split('.').collect();
|
|
||||||
|
|
||||||
if let UntaggedValue::Row(ref mut o) = new_obj.value {
|
|
||||||
let mut current = o;
|
|
||||||
|
|
||||||
if split_path.len() == 1 {
|
|
||||||
// Special case for inserting at the top level
|
|
||||||
current.entries.insert(
|
|
||||||
path.to_string(),
|
|
||||||
new_value.value.clone().into_value(&value.tag),
|
|
||||||
);
|
|
||||||
return Some(new_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
for idx in 0..split_path.len() {
|
|
||||||
match current.entries.get_mut(split_path[idx]) {
|
|
||||||
Some(next) => {
|
|
||||||
if idx == (split_path.len() - 2) {
|
|
||||||
if let UntaggedValue::Row(o) = &mut next.value {
|
|
||||||
o.entries.insert(
|
|
||||||
split_path[idx + 1].to_string(),
|
|
||||||
new_value.value.clone().into_value(&value.tag),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Some(new_obj.clone());
|
|
||||||
} else {
|
|
||||||
match next.value {
|
|
||||||
UntaggedValue::Row(ref mut o) => {
|
|
||||||
current = o;
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_data_at_member(
|
|
||||||
value: &mut Value,
|
|
||||||
member: &PathMember,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<(), ShellError> {
|
|
||||||
match &mut value.value {
|
|
||||||
UntaggedValue::Row(dict) => match &member.unspanned {
|
|
||||||
UnspannedPathMember::String(key) => {
|
|
||||||
dict.insert_data_at_key(key, new_value);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
UnspannedPathMember::Int(_) => Err(ShellError::type_error(
|
|
||||||
"column name",
|
|
||||||
"integer".spanned(member.span),
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
UntaggedValue::Table(array) => match &member.unspanned {
|
|
||||||
UnspannedPathMember::String(_) => Err(ShellError::type_error(
|
|
||||||
"list index",
|
|
||||||
"string".spanned(member.span),
|
|
||||||
)),
|
|
||||||
UnspannedPathMember::Int(int) => {
|
|
||||||
let int = int.to_usize().ok_or_else(|| {
|
|
||||||
ShellError::range_error(
|
|
||||||
ExpectedRange::Usize,
|
|
||||||
&"bigger number".spanned(member.span),
|
|
||||||
"inserting into a list",
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
insert_data_at_index(array, int.tagged(member.span), new_value.clone())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
other => match &member.unspanned {
|
|
||||||
UnspannedPathMember::String(_) => Err(ShellError::type_error(
|
|
||||||
"row",
|
|
||||||
other.type_name().spanned(value.span()),
|
|
||||||
)),
|
|
||||||
UnspannedPathMember::Int(_) => Err(ShellError::type_error(
|
|
||||||
"table",
|
|
||||||
other.type_name().spanned(value.span()),
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn insert_data_at_column_path(
|
|
||||||
value: &Value,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<Value, ShellError> {
|
|
||||||
let (last, front) = split_path.split_last();
|
|
||||||
let mut original = value.clone();
|
|
||||||
|
|
||||||
let mut current: &mut Value = &mut original;
|
|
||||||
|
|
||||||
for member in front {
|
|
||||||
let type_name = current.spanned_type_name();
|
|
||||||
|
|
||||||
current = get_mut_data_by_member(current, &member).ok_or_else(|| {
|
|
||||||
ShellError::missing_property(
|
|
||||||
member.plain_string(std::usize::MAX).spanned(member.span),
|
|
||||||
type_name,
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
|
|
||||||
insert_data_at_member(current, &last, new_value)?;
|
|
||||||
|
|
||||||
Ok(original)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn replace_data_at_column_path(
|
|
||||||
value: &Value,
|
|
||||||
split_path: &ColumnPath,
|
|
||||||
replaced_value: Value,
|
|
||||||
) -> Option<Value> {
|
|
||||||
let mut new_obj: Value = value.clone();
|
|
||||||
let mut current = &mut new_obj;
|
|
||||||
let split_path = split_path.members();
|
|
||||||
|
|
||||||
for idx in 0..split_path.len() {
|
|
||||||
match get_mut_data_by_member(current, &split_path[idx]) {
|
|
||||||
Some(next) => {
|
|
||||||
if idx == (split_path.len() - 1) {
|
|
||||||
*next = replaced_value.value.into_value(&value.tag);
|
|
||||||
return Some(new_obj);
|
|
||||||
} else {
|
|
||||||
current = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_column_path(value: &Value) -> Result<Tagged<ColumnPath>, ShellError> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Table(table) => {
|
|
||||||
let mut out: Vec<PathMember> = vec![];
|
|
||||||
|
|
||||||
for item in table {
|
|
||||||
out.push(as_path_member(item)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(ColumnPath::new(out).tagged(&value.tag))
|
|
||||||
}
|
|
||||||
|
|
||||||
UntaggedValue::Primitive(Primitive::String(s)) => {
|
|
||||||
Ok(ColumnPath::new(vec![PathMember::string(s, &value.tag.span)]).tagged(&value.tag))
|
|
||||||
}
|
|
||||||
|
|
||||||
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
|
|
||||||
Ok(path.clone().tagged(value.tag.clone()))
|
|
||||||
}
|
|
||||||
|
|
||||||
other => Err(ShellError::type_error(
|
|
||||||
"column path",
|
|
||||||
other.type_name().spanned(value.span()),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_path_member(value: &Value) -> Result<PathMember, ShellError> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Primitive(primitive) => match primitive {
|
|
||||||
Primitive::Int(int) => Ok(PathMember::int(int.clone(), value.tag.span)),
|
|
||||||
Primitive::String(string) => Ok(PathMember::string(string, value.tag.span)),
|
|
||||||
other => Err(ShellError::type_error(
|
|
||||||
"path member",
|
|
||||||
other.type_name().spanned(value.span()),
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
other => Err(ShellError::type_error(
|
|
||||||
"path member",
|
|
||||||
other.type_name().spanned(value.span()),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_string(value: &Value) -> Result<String, ShellError> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Primitive(Primitive::String(s)) => Ok(s.clone()),
|
|
||||||
UntaggedValue::Primitive(Primitive::Boolean(x)) => Ok(format!("{}", x)),
|
|
||||||
UntaggedValue::Primitive(Primitive::Decimal(x)) => Ok(format!("{}", x)),
|
|
||||||
UntaggedValue::Primitive(Primitive::Int(x)) => Ok(format!("{}", x)),
|
|
||||||
UntaggedValue::Primitive(Primitive::Bytes(x)) => Ok(format!("{}", x)),
|
|
||||||
UntaggedValue::Primitive(Primitive::Path(x)) => Ok(format!("{}", x.display())),
|
|
||||||
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
|
|
||||||
Ok(path.iter().map(|member| member.display()).join("."))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: this should definitely be more general with better errors
|
|
||||||
other => Err(ShellError::labeled_error(
|
|
||||||
"Expected string",
|
|
||||||
other.type_name(),
|
|
||||||
&value.tag,
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_data_at_index(
|
|
||||||
list: &mut Vec<Value>,
|
|
||||||
index: Tagged<usize>,
|
|
||||||
new_value: Value,
|
|
||||||
) -> Result<(), ShellError> {
|
|
||||||
if list.len() >= index.item {
|
|
||||||
Err(ShellError::range_error(
|
|
||||||
0..(list.len()),
|
|
||||||
&format_args!("{}", index.item).spanned(index.tag.span),
|
|
||||||
"insert at index",
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
list[index.item] = new_value;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_data<'value>(value: &'value Value, desc: &String) -> MaybeOwned<'value, Value> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Primitive(_) => MaybeOwned::Borrowed(value),
|
|
||||||
UntaggedValue::Row(o) => o.get_data(desc),
|
|
||||||
UntaggedValue::Block(_) | UntaggedValue::Table(_) | UntaggedValue::Error(_) => {
|
|
||||||
MaybeOwned::Owned(UntaggedValue::nothing().into_untagged_value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_data_by_index(value: &Value, idx: Spanned<usize>) -> Option<Value> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Table(value_set) => {
|
|
||||||
let value = value_set.get(idx.item)?;
|
|
||||||
Some(
|
|
||||||
value
|
|
||||||
.value
|
|
||||||
.clone()
|
|
||||||
.into_value(Tag::new(value.anchor(), idx.span)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_data_by_key(value: &Value, name: Spanned<&str>) -> Option<Value> {
|
|
||||||
match &value.value {
|
|
||||||
UntaggedValue::Row(o) => o.get_data_by_key(name),
|
|
||||||
UntaggedValue::Table(l) => {
|
|
||||||
let mut out = vec![];
|
|
||||||
for item in l {
|
|
||||||
match item {
|
|
||||||
Value {
|
|
||||||
value: UntaggedValue::Row(o),
|
|
||||||
..
|
|
||||||
} => match o.get_data_by_key(name) {
|
|
||||||
Some(v) => out.push(v),
|
|
||||||
None => out.push(UntaggedValue::nothing().into_untagged_value()),
|
|
||||||
},
|
|
||||||
_ => out.push(UntaggedValue::nothing().into_untagged_value()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !out.is_empty() {
|
|
||||||
Some(UntaggedValue::Table(out).into_value(name.span))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_mut_data_by_member<'value>(
|
|
||||||
value: &'value mut Value,
|
|
||||||
name: &PathMember,
|
|
||||||
) -> Option<&'value mut Value> {
|
|
||||||
match &mut value.value {
|
|
||||||
UntaggedValue::Row(o) => match &name.unspanned {
|
|
||||||
UnspannedPathMember::String(string) => o.get_mut_data_by_key(&string),
|
|
||||||
UnspannedPathMember::Int(_) => None,
|
|
||||||
},
|
|
||||||
UntaggedValue::Table(l) => match &name.unspanned {
|
|
||||||
UnspannedPathMember::String(string) => {
|
|
||||||
for item in l {
|
|
||||||
if let Value {
|
|
||||||
value: UntaggedValue::Row(o),
|
|
||||||
..
|
|
||||||
} = item
|
|
||||||
{
|
|
||||||
if let Some(v) = o.get_mut_data_by_key(&string) {
|
|
||||||
return Some(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
UnspannedPathMember::Int(int) => {
|
|
||||||
let index = int.to_usize()?;
|
|
||||||
l.get_mut(index)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::data::base::property_get::ValueExt;
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use nu_errors::{CoerceInto, ShellError};
|
use nu_errors::{CoerceInto, ShellError};
|
||||||
use nu_protocol::{CallInfo, ColumnPath, Evaluate, Primitive, ShellTypeName, UntaggedValue, Value};
|
use nu_protocol::{CallInfo, ColumnPath, Evaluate, Primitive, ShellTypeName, UntaggedValue, Value};
|
||||||
use nu_source::{HasSpan, SpannedItem, Tagged, TaggedItem};
|
use nu_source::{HasSpan, SpannedItem, Tagged, TaggedItem};
|
||||||
|
use nu_value_ext::ValueExt;
|
||||||
use serde::de;
|
use serde::de;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ mod stream;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub use crate::cli::cli;
|
pub use crate::cli::cli;
|
||||||
pub use crate::data::base::property_get::ValueExt;
|
|
||||||
pub use crate::data::config::{config_path, APP_INFO};
|
pub use crate::data::config::{config_path, APP_INFO};
|
||||||
pub use crate::data::dict::TaggedListBuilder;
|
pub use crate::data::dict::TaggedListBuilder;
|
||||||
pub use crate::data::primitive;
|
pub use crate::data::primitive;
|
||||||
|
@ -29,6 +28,7 @@ pub use crate::data::value;
|
||||||
pub use crate::env::host::BasicHost;
|
pub use crate::env::host::BasicHost;
|
||||||
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
|
pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath};
|
||||||
pub use nu_parser::TokenTreeBuilder;
|
pub use nu_parser::TokenTreeBuilder;
|
||||||
|
pub use nu_value_ext::ValueExt;
|
||||||
pub use num_traits::cast::ToPrimitive;
|
pub use num_traits::cast::ToPrimitive;
|
||||||
|
|
||||||
// TODO: Temporary redirect
|
// TODO: Temporary redirect
|
||||||
|
|
|
@ -75,7 +75,6 @@ pub(crate) use crate::commands::command::{
|
||||||
};
|
};
|
||||||
pub(crate) use crate::context::CommandRegistry;
|
pub(crate) use crate::context::CommandRegistry;
|
||||||
pub(crate) use crate::context::Context;
|
pub(crate) use crate::context::Context;
|
||||||
pub(crate) use crate::data::base::property_get::ValueExt;
|
|
||||||
pub(crate) use crate::data::types::ExtractType;
|
pub(crate) use crate::data::types::ExtractType;
|
||||||
pub(crate) use crate::data::value;
|
pub(crate) use crate::data::value;
|
||||||
pub(crate) use crate::env::host::handle_unexpected;
|
pub(crate) use crate::env::host::handle_unexpected;
|
||||||
|
@ -94,6 +93,7 @@ pub(crate) use nu_source::{
|
||||||
b, AnchorLocation, DebugDocBuilder, HasSpan, PrettyDebug, PrettyDebugWithSource, Span,
|
b, AnchorLocation, DebugDocBuilder, HasSpan, PrettyDebug, PrettyDebugWithSource, Span,
|
||||||
SpannedItem, Tag, TaggedItem, Text,
|
SpannedItem, Tag, TaggedItem, Text,
|
||||||
};
|
};
|
||||||
|
pub(crate) use nu_value_ext::ValueExt;
|
||||||
pub(crate) use num_bigint::BigInt;
|
pub(crate) use num_bigint::BigInt;
|
||||||
pub(crate) use num_traits::cast::ToPrimitive;
|
pub(crate) use num_traits::cast::ToPrimitive;
|
||||||
pub(crate) use serde::Deserialize;
|
pub(crate) use serde::Deserialize;
|
||||||
|
|
Loading…
Reference in a new issue