Extract nu_source into a crate

This commit extracts Tag, Span, Text, as well as source-related debug
facilities into a new crate called nu_source.

This change is much bigger than one might have expected because the
previous code relied heavily on implementing inherent methods on
`Tagged<T>` and `Spanned<T>`, which is no longer possible.

As a result, this change creates more concrete types instead of using
`Tagged<T>`. One notable example: Tagged<Value> became Value, and Value
became UntaggedValue.

This change clarifies the intent of the code in many places, but it does
make it a big change.
This commit is contained in:
Yehuda Katz
2019-11-21 06:33:14 -08:00
parent fe53c37654
commit f70c6d5d48
173 changed files with 4958 additions and 4210 deletions

View File

@ -1,11 +1,12 @@
use nu::{
serve_plugin, CallInfo, CoerceInto, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
Signature, Tagged, TaggedItem, Value,
Signature, UntaggedValue, Value,
};
use nu_source::TaggedItem;
#[derive(Debug)]
struct Average {
total: Option<Tagged<Value>>,
total: Option<Value>,
count: u64,
}
@ -17,15 +18,15 @@ impl Average {
}
}
fn average(&mut self, value: Tagged<Value>) -> Result<(), ShellError> {
match value.item() {
Value::Primitive(Primitive::Nothing) => Ok(()),
Value::Primitive(Primitive::Int(i)) => match &self.total {
Some(Tagged {
item: Value::Primitive(Primitive::Int(j)),
fn average(&mut self, value: Value) -> Result<(), ShellError> {
match &value.value {
UntaggedValue::Primitive(Primitive::Nothing) => Ok(()),
UntaggedValue::Primitive(Primitive::Int(i)) => match &self.total {
Some(Value {
value: UntaggedValue::Primitive(Primitive::Int(j)),
tag,
}) => {
self.total = Some(Value::int(i + j).tagged(tag));
self.total = Some(UntaggedValue::int(i + j).into_value(tag));
self.count += 1;
Ok(())
}
@ -40,12 +41,12 @@ impl Average {
value.tag,
)),
},
Value::Primitive(Primitive::Bytes(b)) => match &self.total {
Some(Tagged {
item: Value::Primitive(Primitive::Bytes(j)),
UntaggedValue::Primitive(Primitive::Bytes(b)) => match &self.total {
Some(Value {
value: UntaggedValue::Primitive(Primitive::Bytes(j)),
tag,
}) => {
self.total = Some(Value::bytes(b + j).tagged(tag));
self.total = Some(UntaggedValue::bytes(b + j).into_value(tag));
self.count += 1;
Ok(())
}
@ -80,7 +81,7 @@ impl Plugin for Average {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
self.average(input)?;
Ok(vec![])
}
@ -88,20 +89,20 @@ impl Plugin for Average {
fn end_filter(&mut self) -> Result<Vec<ReturnValue>, ShellError> {
match self.total {
None => Ok(vec![]),
Some(ref inner) => match inner.item() {
Value::Primitive(Primitive::Int(i)) => {
Some(ref inner) => match &inner.value {
UntaggedValue::Primitive(Primitive::Int(i)) => {
let total: u64 = i
.tagged(inner.tag.clone())
.coerce_into("converting for average")?;
let avg = total as f64 / self.count as f64;
let primitive_value: Value = Primitive::from(avg).into();
let tagged_value = primitive_value.tagged(inner.tag.clone());
Ok(vec![ReturnSuccess::value(tagged_value)])
let primitive_value: UntaggedValue = Primitive::from(avg).into();
let value = primitive_value.into_value(inner.tag.clone());
Ok(vec![ReturnSuccess::value(value)])
}
Value::Primitive(Primitive::Bytes(bytes)) => {
UntaggedValue::Primitive(Primitive::Bytes(bytes)) => {
let avg = *bytes as f64 / self.count as f64;
let primitive_value: Value = Primitive::from(avg).into();
let tagged_value = primitive_value.tagged(inner.tag.clone());
let primitive_value: UntaggedValue = Primitive::from(avg).into();
let tagged_value = primitive_value.into_value(inner.tag.clone());
Ok(vec![ReturnSuccess::value(tagged_value)])
}
_ => Ok(vec![]),

View File

@ -1,8 +1,8 @@
use crossterm::{cursor, terminal, Attribute, RawScreen};
use nu::{
outln, serve_plugin, AnchorLocation, CallInfo, Plugin, Primitive, ShellError, Signature,
Tagged, Value,
outln, serve_plugin, CallInfo, Plugin, Primitive, ShellError, Signature, UntaggedValue, Value,
};
use nu_source::AnchorLocation;
use pretty_hex::*;
struct BinaryView;
@ -20,11 +20,11 @@ impl Plugin for BinaryView {
.switch("lores", "use low resolution output mode"))
}
fn sink(&mut self, call_info: CallInfo, input: Vec<Tagged<Value>>) {
fn sink(&mut self, call_info: CallInfo, input: Vec<Value>) {
for v in input {
let value_anchor = v.anchor();
match v.item {
Value::Primitive(Primitive::Binary(b)) => {
match &v.value {
UntaggedValue::Primitive(Primitive::Binary(b)) => {
let _ = view_binary(&b, value_anchor.as_ref(), call_info.args.has("lores"));
}
_ => {}

View File

@ -15,7 +15,7 @@ impl Docker {
}
}
async fn docker(sub_command: &String, name: Tag) -> Result<Vec<Tagged<Value>>, ShellError> {
async fn docker(sub_command: &String, name: Tag) -> Result<Vec<Value>, ShellError> {
match sub_command.as_str() {
"ps" => docker_ps(name),
"images" => docker_images(name),
@ -27,7 +27,7 @@ async fn docker(sub_command: &String, name: Tag) -> Result<Vec<Tagged<Value>>, S
}
}
fn process_docker_output(cmd_output: &str, tag: Tag) -> Result<Vec<Tagged<Value>>, ShellError> {
fn process_docker_output(cmd_output: &str, tag: Tag) -> Result<Vec<Value>, ShellError> {
let columns: Vec<&str> = cmd_output.lines().collect();
let header: Vec<&str> = columns
@ -48,16 +48,19 @@ fn process_docker_output(cmd_output: &str, tag: Tag) -> Result<Vec<Tagged<Value>
let mut dict = TaggedDictBuilder::new(&tag);
for (i, v) in values.iter().enumerate() {
dict.insert(header[i].to_string(), Value::string(v.trim().to_string()));
dict.insert(
header[i].to_string(),
UntaggedValue::string(v.trim().to_string()),
);
}
output.push(dict.into_tagged_value());
output.push(dict.into_value());
}
Ok(output)
}
pub fn docker_images(tag: Tag) -> Result<Vec<Tagged<Value>>, ShellError> {
pub fn docker_images(tag: Tag) -> Result<Vec<Value>, ShellError> {
let output = Command::new("docker")
.arg("images")
.output()
@ -69,7 +72,7 @@ pub fn docker_images(tag: Tag) -> Result<Vec<Tagged<Value>>, ShellError> {
out
}
pub fn docker_ps(tag: Tag) -> Result<Vec<Tagged<Value>>, ShellError> {
pub fn docker_ps(tag: Tag) -> Result<Vec<Value>, ShellError> {
let output = Command::new("docker")
.arg("ps")
.output()
@ -91,8 +94,8 @@ impl Plugin for Docker {
fn begin_filter(&mut self, callinfo: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = callinfo.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(command)),
Value {
value: UntaggedValue::Primitive(Primitive::String(command)),
..
} => match block_on(docker(&command, args[0].tag())) {
Ok(v) => return Ok(v.into_iter().map(ReturnSuccess::value).collect()),
@ -105,7 +108,7 @@ impl Plugin for Docker {
Ok(vec![])
}
fn filter(&mut self, _: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, _: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![])
}
}

View File

@ -1,11 +1,12 @@
use nu::{
serve_plugin, CallInfo, ColumnPath, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
ShellTypeName, Signature, SpannedItem, SyntaxShape, Tagged, TaggedItem, Value,
Signature, SpannedTypeName, SyntaxShape, UntaggedValue, Value,
};
use nu_source::Tagged;
struct Edit {
field: Option<Tagged<ColumnPath>>,
value: Option<Value>,
value: Option<UntaggedValue>,
}
impl Edit {
fn new() -> Edit {
@ -15,20 +16,28 @@ impl Edit {
}
}
fn edit(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
fn edit(&self, value: Value) -> Result<Value, ShellError> {
let value_tag = value.tag();
match (value.item, self.value.clone()) {
(obj @ Value::Row(_), Some(v)) => match &self.field {
Some(f) => match obj.tagged(value_tag).replace_data_at_column_path(&f, v) {
Some(v) => return Ok(v),
None => {
return Err(ShellError::labeled_error(
"edit could not find place to insert column",
"column name",
&f.tag,
))
}
match (value, self.value.clone()) {
(
obj @ Value {
value: UntaggedValue::Row(_),
..
},
Some(v),
) => match &self.field {
Some(f) => {
match obj.replace_data_at_column_path(&f, v.clone().into_untagged_value()) {
Some(v) => return Ok(v),
None => {
return Err(ShellError::labeled_error(
"edit could not find place to insert column",
"column name",
&f.tag,
))
}
}
}
None => Err(ShellError::untagged_runtime_error(
"edit needs a column when changing a value in a table",
)),
@ -62,21 +71,17 @@ impl Plugin for Edit {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
table @ Tagged {
item: Value::Primitive(Primitive::ColumnPath(_)),
table @ Value {
value: UntaggedValue::Primitive(Primitive::ColumnPath(_)),
..
} => {
self.field = Some(table.as_column_path()?);
}
value => {
return Err(ShellError::type_error(
"table",
value.type_name().spanned(value.span()),
))
}
value => return Err(ShellError::type_error("table", value.spanned_type_name())),
}
match &args[1] {
Tagged { item: v, .. } => {
Value { value: v, .. } => {
self.value = Some(v.clone());
}
}
@ -85,7 +90,7 @@ impl Plugin for Edit {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.edit(input)?)])
}
}

View File

@ -2,13 +2,14 @@
extern crate indexmap;
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
ShellTypeName, Signature, SpannedItem, SyntaxShape, Tag, Tagged, TaggedItem, Value,
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SpannedTypeName, SyntaxShape, UntaggedValue, Value,
};
use nu_source::Tag;
struct Embed {
field: Option<String>,
values: Vec<Tagged<Value>>,
values: Vec<Value>,
}
impl Embed {
fn new() -> Embed {
@ -18,7 +19,7 @@ impl Embed {
}
}
fn embed(&mut self, value: Tagged<Value>) -> Result<(), ShellError> {
fn embed(&mut self, value: Value) -> Result<(), ShellError> {
self.values.push(value);
Ok(())
}
@ -35,38 +36,33 @@ impl Plugin for Embed {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
self.field = Some(s.clone());
self.values = Vec::new();
}
value => {
return Err(ShellError::type_error(
"string",
value.type_name().spanned(value.span()),
))
}
value => return Err(ShellError::type_error("string", value.spanned_type_name())),
}
}
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
self.embed(input)?;
Ok(vec![])
}
fn end_filter(&mut self) -> Result<Vec<ReturnValue>, ShellError> {
let row = Value::row(indexmap! {
let row = UntaggedValue::row(indexmap! {
match &self.field {
Some(key) => key.clone(),
None => "root".into(),
} => Value::table(&self.values).tagged(Tag::unknown()),
} => UntaggedValue::table(&self.values).into_value(Tag::unknown()),
})
.tagged(Tag::unknown());
.into_untagged_value();
Ok(vec![ReturnSuccess::value(row)])
}

View File

@ -1,6 +1,6 @@
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxShape, Tagged, TaggedItem, Value,
SyntaxShape, UntaggedValue, Value,
};
use nom::{
@ -66,14 +66,14 @@ impl Plugin for Format {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(pattern)),
Value {
value: UntaggedValue::Primitive(Primitive::String(pattern)),
..
} => {
let format_pattern = format(&pattern).unwrap();
self.commands = format_pattern.1
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Unrecognized type in params",
"expected a string",
@ -85,10 +85,10 @@ impl Plugin for Format {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
match &input {
Tagged {
item: Value::Row(dict),
Value {
value: UntaggedValue::Row(dict),
..
} => {
let mut output = String::new();
@ -114,7 +114,7 @@ impl Plugin for Format {
}
return Ok(vec![ReturnSuccess::value(
Value::string(output).tagged_unknown(),
UntaggedValue::string(output).into_untagged_value(),
)]);
}
_ => {}

View File

@ -1,8 +1,8 @@
use nu::{
did_you_mean, serve_plugin, span_for_spanned_list, CallInfo, ColumnPath, Plugin, Primitive,
ReturnSuccess, ReturnValue, ShellError, ShellTypeName, Signature, SpannedItem, SyntaxShape,
Tagged, TaggedItem, Value,
did_you_mean, serve_plugin, CallInfo, ColumnPath, Plugin, Primitive, ReturnSuccess,
ReturnValue, ShellError, ShellTypeName, Signature, SyntaxShape, UntaggedValue, Value,
};
use nu_source::{span_for_spanned_list, HasSpan, SpannedItem, Tagged};
enum Action {
SemVerAction(SemVerAction),
@ -30,12 +30,12 @@ impl Inc {
}
}
fn apply(&self, input: &str) -> Result<Value, ShellError> {
fn apply(&self, input: &str) -> Result<UntaggedValue, ShellError> {
let applied = match &self.action {
Some(Action::SemVerAction(act_on)) => {
let mut ver = match semver::Version::parse(&input) {
Ok(parsed_ver) => parsed_ver,
Err(_) => return Ok(Value::string(input.to_string())),
Err(_) => return Ok(UntaggedValue::string(input.to_string())),
};
match act_on {
@ -44,11 +44,11 @@ impl Inc {
SemVerAction::Patch => ver.increment_patch(),
}
Value::string(ver.to_string())
UntaggedValue::string(ver.to_string())
}
Some(Action::Default) | None => match input.parse::<u64>() {
Ok(v) => Value::string(format!("{}", v + 1)),
Err(_) => Value::string(input),
Ok(v) => UntaggedValue::string(format!("{}", v + 1)),
Err(_) => UntaggedValue::string(input),
},
};
@ -75,16 +75,21 @@ impl Inc {
"Usage: inc field [--major|--minor|--patch]"
}
fn inc(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
match value.item() {
Value::Primitive(Primitive::Int(i)) => Ok(Value::int(i + 1).tagged(value.tag())),
Value::Primitive(Primitive::Bytes(b)) => {
Ok(Value::bytes(b + 1 as u64).tagged(value.tag()))
fn inc(&self, value: Value) -> Result<Value, ShellError> {
match &value.value {
UntaggedValue::Primitive(Primitive::Int(i)) => {
Ok(UntaggedValue::int(i + 1).into_value(value.tag()))
}
Value::Primitive(Primitive::String(ref s)) => Ok(self.apply(&s)?.tagged(value.tag())),
Value::Table(values) => {
UntaggedValue::Primitive(Primitive::Bytes(b)) => {
Ok(UntaggedValue::bytes(b + 1 as u64).into_value(value.tag()))
}
UntaggedValue::Primitive(Primitive::String(ref s)) => {
Ok(self.apply(&s)?.into_value(value.tag()))
}
UntaggedValue::Table(values) => {
if values.len() == 1 {
return Ok(Value::Table(vec![self.inc(values[0].clone())?]).tagged(value.tag()));
return Ok(UntaggedValue::Table(vec![self.inc(values[0].clone())?])
.into_value(value.tag()));
} else {
return Err(ShellError::type_error(
"incrementable value",
@ -93,7 +98,7 @@ impl Inc {
}
}
Value::Row(_) => match self.field {
UntaggedValue::Row(_) => match self.field {
Some(ref f) => {
let fields = f.clone();
@ -120,9 +125,12 @@ impl Inc {
);
let got = replace_for?;
let replacement = self.inc(got.map(|x| x.clone()))?;
let replacement = self.inc(got.clone())?;
match value.replace_data_at_column_path(&f, replacement.item.clone()) {
match value.replace_data_at_column_path(
&f,
replacement.value.clone().into_untagged_value(),
) {
Some(v) => return Ok(v),
None => {
return Err(ShellError::labeled_error(
@ -170,8 +178,8 @@ impl Plugin for Inc {
if let Some(args) = call_info.args.positional {
for arg in args {
match arg {
table @ Tagged {
item: Value::Primitive(Primitive::ColumnPath(_)),
table @ Value {
value: UntaggedValue::Primitive(Primitive::ColumnPath(_)),
..
} => {
self.field = Some(table.as_column_path()?);
@ -202,7 +210,7 @@ impl Plugin for Inc {
}
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.inc(input)?)])
}
}
@ -217,13 +225,14 @@ mod tests {
use super::{Inc, SemVerAction};
use indexmap::IndexMap;
use nu::{
CallInfo, EvaluatedArgs, PathMember, Plugin, RawPathMember, ReturnSuccess, SpannedItem,
Tag, Tagged, TaggedDictBuilder, TaggedItem, Value,
CallInfo, EvaluatedArgs, PathMember, Plugin, ReturnSuccess, TaggedDictBuilder,
UnspannedPathMember, UntaggedValue, Value,
};
use nu_source::{Span, Tag};
struct CallStub {
positionals: Vec<Tagged<Value>>,
flags: IndexMap<String, Tagged<Value>>,
positionals: Vec<Value>,
flags: IndexMap<String, Value>,
}
impl CallStub {
@ -237,7 +246,7 @@ mod tests {
fn with_long_flag(&mut self, name: &str) -> &mut Self {
self.flags.insert(
name.to_string(),
Value::boolean(true).tagged(Tag::unknown()),
UntaggedValue::boolean(true).into_value(Tag::unknown()),
);
self
}
@ -245,11 +254,13 @@ mod tests {
fn with_parameter(&mut self, name: &str) -> &mut Self {
let fields: Vec<PathMember> = name
.split(".")
.map(|s| RawPathMember::String(s.to_string()).spanned_unknown())
.map(|s| {
UnspannedPathMember::String(s.to_string()).into_path_member(Span::unknown())
})
.collect();
self.positionals
.push(Value::column_path(fields).tagged_unknown());
.push(UntaggedValue::column_path(fields).into_untagged_value());
self
}
@ -261,10 +272,10 @@ mod tests {
}
}
fn cargo_sample_record(with_version: &str) -> Tagged<Value> {
fn cargo_sample_record(with_version: &str) -> Value {
let mut package = TaggedDictBuilder::new(Tag::unknown());
package.insert("version", Value::string(with_version));
package.into_tagged_value()
package.insert_untagged("version", UntaggedValue::string(with_version));
package.into_value()
}
#[test]
@ -334,10 +345,10 @@ mod tests {
assert_eq!(
plugin
.field
.map(|f| f.iter().map(|f| f.item.clone()).collect()),
.map(|f| f.iter().map(|f| f.unspanned.clone()).collect()),
Some(vec![
RawPathMember::String("package".to_string()),
RawPathMember::String("version".to_string())
UnspannedPathMember::String("package".to_string()),
UnspannedPathMember::String("version".to_string())
])
);
}
@ -346,21 +357,21 @@ mod tests {
fn incs_major() {
let mut inc = Inc::new();
inc.for_semver(SemVerAction::Major);
assert_eq!(inc.apply("0.1.3").unwrap(), Value::string("1.0.0"));
assert_eq!(inc.apply("0.1.3").unwrap(), UntaggedValue::string("1.0.0"));
}
#[test]
fn incs_minor() {
let mut inc = Inc::new();
inc.for_semver(SemVerAction::Minor);
assert_eq!(inc.apply("0.1.3").unwrap(), Value::string("0.2.0"));
assert_eq!(inc.apply("0.1.3").unwrap(), UntaggedValue::string("0.2.0"));
}
#[test]
fn incs_patch() {
let mut inc = Inc::new();
inc.for_semver(SemVerAction::Patch);
assert_eq!(inc.apply("0.1.3").unwrap(), Value::string("0.1.4"));
assert_eq!(inc.apply("0.1.3").unwrap(), UntaggedValue::string("0.1.4"));
}
#[test]
@ -380,12 +391,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&String::from("version")).borrow(),
Value::string(String::from("1.0.0"))
UntaggedValue::string(String::from("1.0.0")).into_untagged_value()
),
_ => {}
}
@ -408,12 +419,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&String::from("version")).borrow(),
Value::string(String::from("0.2.0"))
UntaggedValue::string(String::from("0.2.0")).into_untagged_value()
),
_ => {}
}
@ -437,12 +448,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&field).borrow(),
Value::string(String::from("0.1.4"))
UntaggedValue::string(String::from("0.1.4")).into_untagged_value()
),
_ => {}
}

View File

@ -1,11 +1,12 @@
use nu::{
serve_plugin, CallInfo, ColumnPath, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
ShellTypeName, Signature, SpannedItem, SyntaxShape, Tagged, Value,
ShellTypeName, Signature, SpannedTypeName, SyntaxShape, UntaggedValue, Value,
};
use nu_source::SpannedItem;
struct Insert {
field: Option<ColumnPath>,
value: Option<Tagged<Value>>,
value: Option<Value>,
}
impl Insert {
fn new() -> Insert {
@ -15,13 +16,13 @@ impl Insert {
}
}
fn insert(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
fn insert(&self, value: Value) -> Result<Value, ShellError> {
let value_tag = value.tag();
match (&value, &self.value, &self.field) {
(
obj @ Tagged {
item: Value::Row(_),
obj @ Value {
value: UntaggedValue::Row(_),
..
},
Some(v),
@ -55,31 +56,23 @@ impl Plugin for Insert {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
table @ Tagged {
item: Value::Primitive(Primitive::ColumnPath(_)),
table @ Value {
value: UntaggedValue::Primitive(Primitive::ColumnPath(_)),
..
} => {
self.field = Some(table.as_column_path()?.item);
}
value => {
return Err(ShellError::type_error(
"table",
value.type_name().spanned(value.span()),
))
}
}
match &args[1] {
v @ Tagged { .. } => {
self.value = Some(v.clone());
}
value => return Err(ShellError::type_error("table", value.spanned_type_name())),
}
self.value = Some(args[1].clone());
}
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.insert(input)?)])
}
}

View File

@ -1,7 +1,8 @@
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxShape, Tagged, Value,
SyntaxShape, UntaggedValue, Value,
};
use regex::Regex;
struct Match {
@ -29,13 +30,13 @@ impl Plugin for Match {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
self.column = s.clone();
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Unrecognized type in params",
"value",
@ -44,13 +45,13 @@ impl Plugin for Match {
}
}
match &args[1] {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
self.regex = Regex::new(s).unwrap();
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Unrecognized type in params",
"value",
@ -62,22 +63,22 @@ impl Plugin for Match {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
let flag: bool;
match &input {
Tagged {
item: Value::Row(dict),
Value {
value: UntaggedValue::Row(dict),
tag,
} => {
if let Some(val) = dict.entries.get(&self.column) {
match val {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
flag = self.regex.is_match(s);
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error("expected string", "value", tag));
}
}
@ -89,7 +90,7 @@ impl Plugin for Match {
));
}
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error("Expected row", "value", tag));
}
}

View File

@ -1,6 +1,6 @@
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxShape, Tagged, TaggedDictBuilder, Value,
SyntaxShape, TaggedDictBuilder, UntaggedValue, Value,
};
use nom::{
@ -102,8 +102,8 @@ impl Plugin for Parse {
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(pattern)),
Value {
value: UntaggedValue::Primitive(Primitive::String(pattern)),
..
} => {
//self.pattern = s.clone();
@ -114,7 +114,7 @@ impl Plugin for Parse {
self.regex = Regex::new(&parse_regex).unwrap();
}
Tagged { tag, .. } => {
Value { tag, .. } => {
return Err(ShellError::labeled_error(
"Unrecognized type in params",
"expected a string",
@ -126,12 +126,12 @@ impl Plugin for Parse {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
let mut results = vec![];
match &input {
Tagged {
Value {
tag,
item: Value::Primitive(Primitive::String(s)),
value: UntaggedValue::Primitive(Primitive::String(s)),
} => {
//self.full_input.push_str(&s);
@ -139,10 +139,13 @@ impl Plugin for Parse {
let mut dict = TaggedDictBuilder::new(tag);
for (idx, column_name) in self.column_names.iter().enumerate() {
dict.insert(column_name, Value::string(&cap[idx + 1].to_string()));
dict.insert_untagged(
column_name,
UntaggedValue::string(&cap[idx + 1].to_string()),
);
}
results.push(ReturnSuccess::value(dict.into_tagged_value()));
results.push(ReturnSuccess::value(dict.into_value()));
}
}
_ => {}

View File

@ -6,9 +6,11 @@ use heim::units::{ratio, Ratio};
use std::usize;
use nu::{
serve_plugin, CallInfo, Plugin, ReturnSuccess, ReturnValue, ShellError, Signature, Tag, Tagged,
TaggedDictBuilder, Value,
serve_plugin, CallInfo, Plugin, ReturnSuccess, ReturnValue, ShellError, Signature,
TaggedDictBuilder, UntaggedValue, Value,
};
use nu_source::Tag;
use std::time::Duration;
struct Ps;
@ -26,7 +28,7 @@ async fn usage(process: Process) -> ProcessResult<(process::Process, Ratio)> {
Ok((process, usage_2 - usage_1))
}
async fn ps(tag: Tag) -> Vec<Tagged<Value>> {
async fn ps(tag: Tag) -> Vec<Value> {
let processes = process::processes()
.map_ok(|process| {
// Note that there is no `.await` here,
@ -41,15 +43,15 @@ async fn ps(tag: Tag) -> Vec<Tagged<Value>> {
while let Some(res) = processes.next().await {
if let Ok((process, usage)) = res {
let mut dict = TaggedDictBuilder::new(&tag);
dict.insert("pid", Value::int(process.pid()));
dict.insert_untagged("pid", UntaggedValue::int(process.pid()));
if let Ok(name) = process.name().await {
dict.insert("name", Value::string(name));
dict.insert_untagged("name", UntaggedValue::string(name));
}
if let Ok(status) = process.status().await {
dict.insert("status", Value::string(format!("{:?}", status)));
dict.insert_untagged("status", UntaggedValue::string(format!("{:?}", status)));
}
dict.insert("cpu", Value::number(usage.get::<ratio::percent>()));
output.push(dict.into_tagged_value());
dict.insert_untagged("cpu", UntaggedValue::number(usage.get::<ratio::percent>()));
output.push(dict.into_value());
}
}
@ -70,7 +72,7 @@ impl Plugin for Ps {
.collect())
}
fn filter(&mut self, _: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, _: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![])
}
}

View File

@ -1,7 +1,8 @@
use nu::{
serve_plugin, CallInfo, CoerceInto, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
Signature, SyntaxShape, Tagged, TaggedItem, Value,
Signature, SyntaxShape, UntaggedValue, Value,
};
use nu_source::TaggedItem;
struct Skip {
skip_amount: i64,
@ -24,8 +25,8 @@ impl Plugin for Skip {
if let Some(args) = call_info.args.positional {
for arg in args {
match arg {
Tagged {
item: Value::Primitive(Primitive::Int(i)),
Value {
value: UntaggedValue::Primitive(Primitive::Int(i)),
tag,
} => {
self.skip_amount = i.tagged(tag).coerce_into("converting for skip")?;
@ -44,7 +45,7 @@ impl Plugin for Skip {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
if self.skip_amount == 0 {
Ok(vec![ReturnSuccess::value(input)])
} else {

View File

@ -1,8 +1,9 @@
use nu::{
did_you_mean, serve_plugin, span_for_spanned_list, CallInfo, ColumnPath, Plugin, Primitive,
ReturnSuccess, ReturnValue, ShellError, ShellTypeName, Signature, SyntaxShape, Tagged,
TaggedItem, Value,
did_you_mean, serve_plugin, CallInfo, ColumnPath, Plugin, Primitive, ReturnSuccess,
ReturnValue, ShellError, ShellTypeName, Signature, SyntaxShape, UntaggedValue, Value,
};
use nu_source::{span_for_spanned_list, Tagged};
use std::cmp;
#[derive(Debug, Eq, PartialEq)]
@ -30,17 +31,17 @@ impl Str {
}
}
fn apply(&self, input: &str) -> Result<Value, ShellError> {
fn apply(&self, input: &str) -> Result<UntaggedValue, ShellError> {
let applied = match self.action.as_ref() {
Some(Action::Downcase) => Value::string(input.to_ascii_lowercase()),
Some(Action::Upcase) => Value::string(input.to_ascii_uppercase()),
Some(Action::Downcase) => UntaggedValue::string(input.to_ascii_lowercase()),
Some(Action::Upcase) => UntaggedValue::string(input.to_ascii_uppercase()),
Some(Action::Substring(s, e)) => {
let end: usize = cmp::min(*e, input.len());
let start: usize = *s;
if start > input.len() - 1 {
Value::string("")
UntaggedValue::string("")
} else {
Value::string(
UntaggedValue::string(
&input
.chars()
.skip(start)
@ -51,11 +52,11 @@ impl Str {
}
Some(Action::ToInteger) => match input.trim() {
other => match other.parse::<i64>() {
Ok(v) => Value::int(v),
Err(_) => Value::string(input),
Ok(v) => UntaggedValue::int(v),
Err(_) => UntaggedValue::string(input),
},
},
None => Value::string(input),
None => UntaggedValue::string(input),
};
Ok(applied)
@ -122,10 +123,12 @@ impl Str {
}
impl Str {
fn strutils(&self, value: Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
match value.item {
Value::Primitive(Primitive::String(ref s)) => Ok(self.apply(&s)?.tagged(value.tag())),
Value::Row(_) => match self.field {
fn strutils(&self, value: Value) -> Result<Value, ShellError> {
match &value.value {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
Ok(self.apply(&s)?.into_value(value.tag()))
}
UntaggedValue::Row(_) => match self.field {
Some(ref f) => {
let fields = f.clone();
@ -147,9 +150,12 @@ impl Str {
);
let got = replace_for?;
let replacement = self.strutils(got.map(|x| x.clone()))?;
let replacement = self.strutils(got.clone())?;
match value.replace_data_at_column_path(&f, replacement.item.clone()) {
match value.replace_data_at_column_path(
&f,
replacement.value.clone().into_untagged_value(),
) {
Some(v) => return Ok(v),
None => Err(ShellError::labeled_error(
"str could not find field to replace",
@ -166,7 +172,7 @@ impl Str {
},
_ => Err(ShellError::labeled_error(
"Unrecognized type in stream",
value.item.type_name(),
value.type_name(),
value.tag,
)),
}
@ -204,8 +210,8 @@ impl Plugin for Str {
if args.has("substring") {
if let Some(start_end) = args.get("substring") {
match start_end {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
self.for_substring(s.to_string());
@ -228,8 +234,8 @@ impl Plugin for Str {
}
for param in args.positional_iter() {
match param {
Tagged {
item: Value::Primitive(Primitive::String(s)),
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => self.params.as_mut().unwrap().push(String::from(s)),
_ => {}
@ -248,7 +254,7 @@ impl Plugin for Str {
}
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![ReturnSuccess::value(self.strutils(input)?)])
}
}
@ -262,14 +268,15 @@ mod tests {
use super::{Action, Str};
use indexmap::IndexMap;
use nu::{
CallInfo, EvaluatedArgs, Plugin, Primitive, RawPathMember, ReturnSuccess, Tag, Tagged,
TaggedDictBuilder, TaggedItem, Value,
CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, TaggedDictBuilder,
UnspannedPathMember, UntaggedValue, Value,
};
use nu_source::Tag;
use num_bigint::BigInt;
struct CallStub {
positionals: Vec<Tagged<Value>>,
flags: IndexMap<String, Tagged<Value>>,
positionals: Vec<Value>,
flags: IndexMap<String, Value>,
}
impl CallStub {
@ -283,7 +290,7 @@ mod tests {
fn with_named_parameter(&mut self, name: &str, value: &str) -> &mut Self {
self.flags.insert(
name.to_string(),
Value::string(value).tagged(Tag::unknown()),
UntaggedValue::string(value).into_value(Tag::unknown()),
);
self
}
@ -291,19 +298,19 @@ mod tests {
fn with_long_flag(&mut self, name: &str) -> &mut Self {
self.flags.insert(
name.to_string(),
Value::boolean(true).tagged(Tag::unknown()),
UntaggedValue::boolean(true).into_value(Tag::unknown()),
);
self
}
fn with_parameter(&mut self, name: &str) -> &mut Self {
let fields: Vec<Tagged<Value>> = name
let fields: Vec<Value> = name
.split(".")
.map(|s| Value::string(s.to_string()).tagged(Tag::unknown()))
.map(|s| UntaggedValue::string(s.to_string()).into_value(Tag::unknown()))
.collect();
self.positionals
.push(Value::Table(fields).tagged(Tag::unknown()));
.push(UntaggedValue::Table(fields).into_value(Tag::unknown()));
self
}
@ -315,14 +322,14 @@ mod tests {
}
}
fn structured_sample_record(key: &str, value: &str) -> Tagged<Value> {
fn structured_sample_record(key: &str, value: &str) -> Value {
let mut record = TaggedDictBuilder::new(Tag::unknown());
record.insert(key.clone(), Value::string(value));
record.into_tagged_value()
record.insert_untagged(key.clone(), UntaggedValue::string(value));
record.into_value()
}
fn unstructured_sample_record(value: &str) -> Tagged<Value> {
Value::string(value).tagged(Tag::unknown())
fn unstructured_sample_record(value: &str) -> Value {
UntaggedValue::string(value).into_value(Tag::unknown())
}
#[test]
@ -380,10 +387,10 @@ mod tests {
assert_eq!(
plugin
.field
.map(|f| f.iter().cloned().map(|f| f.item).collect()),
.map(|f| f.iter().cloned().map(|f| f.unspanned).collect()),
Some(vec![
RawPathMember::String("package".to_string()),
RawPathMember::String("description".to_string())
UnspannedPathMember::String("package".to_string()),
UnspannedPathMember::String("description".to_string())
])
)
}
@ -409,21 +416,30 @@ mod tests {
fn str_downcases() {
let mut strutils = Str::new();
strutils.for_downcase();
assert_eq!(strutils.apply("ANDRES").unwrap(), Value::string("andres"));
assert_eq!(
strutils.apply("ANDRES").unwrap(),
UntaggedValue::string("andres")
);
}
#[test]
fn str_upcases() {
let mut strutils = Str::new();
strutils.for_upcase();
assert_eq!(strutils.apply("andres").unwrap(), Value::string("ANDRES"));
assert_eq!(
strutils.apply("andres").unwrap(),
UntaggedValue::string("ANDRES")
);
}
#[test]
fn str_to_int() {
let mut strutils = Str::new();
strutils.for_to_int();
assert_eq!(strutils.apply("9999").unwrap(), Value::int(9999 as i64));
assert_eq!(
strutils.apply("9999").unwrap(),
UntaggedValue::int(9999 as i64)
);
}
#[test]
@ -443,12 +459,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&String::from("name")).borrow(),
Value::string(String::from("JOTANDREHUDA"))
UntaggedValue::string(String::from("JOTANDREHUDA")).into_untagged_value()
),
_ => {}
}
@ -466,8 +482,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("JOTANDREHUDA")),
_ => {}
@ -491,12 +507,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&String::from("name")).borrow(),
Value::string(String::from("jotandrehuda"))
UntaggedValue::string(String::from("jotandrehuda")).into_untagged_value()
),
_ => {}
}
@ -514,8 +530,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("jotandrehuda")),
_ => {}
@ -539,12 +555,12 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Row(o),
ReturnSuccess::Value(Value {
value: UntaggedValue::Row(o),
..
}) => assert_eq!(
*o.get_data(&String::from("Nu_birthday")).borrow(),
Value::int(10)
UntaggedValue::int(10).into_untagged_value()
),
_ => {}
}
@ -562,8 +578,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::Int(i)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::Int(i)),
..
}) => assert_eq!(*i, BigInt::from(10)),
_ => {}
@ -586,8 +602,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("0")),
_ => {}
@ -610,8 +626,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("0123456789")),
_ => {}
@ -634,8 +650,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("")),
_ => {}
@ -658,8 +674,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("01234")),
_ => {}
@ -682,8 +698,8 @@ mod tests {
let output = plugin.filter(subject).unwrap();
match output[0].as_ref().unwrap() {
ReturnSuccess::Value(Tagged {
item: Value::Primitive(Primitive::String(s)),
ReturnSuccess::Value(Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
}) => assert_eq!(*s, String::from("23456789")),
_ => {}

View File

@ -1,27 +1,27 @@
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
Tagged, TaggedItem, Value,
UntaggedValue, Value,
};
struct Sum {
total: Option<Tagged<Value>>,
total: Option<Value>,
}
impl Sum {
fn new() -> Sum {
Sum { total: None }
}
fn sum(&mut self, value: Tagged<Value>) -> Result<(), ShellError> {
match value.item() {
Value::Primitive(Primitive::Nothing) => Ok(()),
Value::Primitive(Primitive::Int(i)) => {
fn sum(&mut self, value: Value) -> Result<(), ShellError> {
match &value.value {
UntaggedValue::Primitive(Primitive::Nothing) => Ok(()),
UntaggedValue::Primitive(Primitive::Int(i)) => {
match &self.total {
Some(Tagged {
item: Value::Primitive(Primitive::Int(j)),
Some(Value {
value: UntaggedValue::Primitive(Primitive::Int(j)),
tag,
}) => {
//TODO: handle overflow
self.total = Some(Value::int(i + j).tagged(tag));
self.total = Some(UntaggedValue::int(i + j).into_value(tag));
Ok(())
}
None => {
@ -35,14 +35,14 @@ impl Sum {
)),
}
}
Value::Primitive(Primitive::Bytes(b)) => {
UntaggedValue::Primitive(Primitive::Bytes(b)) => {
match &self.total {
Some(Tagged {
item: Value::Primitive(Primitive::Bytes(j)),
Some(Value {
value: UntaggedValue::Primitive(Primitive::Bytes(j)),
tag,
}) => {
//TODO: handle overflow
self.total = Some(Value::bytes(b + j).tagged(tag));
self.total = Some(UntaggedValue::bytes(b + j).into_value(tag));
Ok(())
}
None => {
@ -76,7 +76,7 @@ impl Plugin for Sum {
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
self.sum(input)?;
Ok(vec![])
}

View File

@ -6,8 +6,9 @@ use heim::units::{frequency, information, thermodynamic_temperature, time};
use heim::{disk, host, memory, net, sensors};
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
Tag, Tagged, TaggedDictBuilder, Value,
TaggedDictBuilder, UntaggedValue, Value,
};
use nu_source::Tag;
struct Sys;
impl Sys {
@ -16,70 +17,70 @@ impl Sys {
}
}
async fn cpu(tag: Tag) -> Option<Tagged<Value>> {
async fn cpu(tag: Tag) -> Option<Value> {
match futures::future::try_join(heim::cpu::logical_count(), heim::cpu::frequency()).await {
Ok((num_cpu, cpu_speed)) => {
let mut cpu_idx = TaggedDictBuilder::with_capacity(tag, 4);
cpu_idx.insert("cores", Primitive::number(num_cpu));
cpu_idx.insert_untagged("cores", Primitive::number(num_cpu));
let current_speed =
(cpu_speed.current().get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0)
.round()
/ 100.0;
cpu_idx.insert("current ghz", Primitive::number(current_speed));
cpu_idx.insert_untagged("current ghz", Primitive::number(current_speed));
if let Some(min_speed) = cpu_speed.min() {
let min_speed =
(min_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round()
/ 100.0;
cpu_idx.insert("min ghz", Primitive::number(min_speed));
cpu_idx.insert_untagged("min ghz", Primitive::number(min_speed));
}
if let Some(max_speed) = cpu_speed.max() {
let max_speed =
(max_speed.get::<frequency::hertz>() as f64 / 1_000_000_000.0 * 100.0).round()
/ 100.0;
cpu_idx.insert("max ghz", Primitive::number(max_speed));
cpu_idx.insert_untagged("max ghz", Primitive::number(max_speed));
}
Some(cpu_idx.into_tagged_value())
Some(cpu_idx.into_value())
}
Err(_) => None,
}
}
async fn mem(tag: Tag) -> Tagged<Value> {
async fn mem(tag: Tag) -> Value {
let mut dict = TaggedDictBuilder::with_capacity(tag, 4);
let (memory_result, swap_result) =
futures::future::join(memory::memory(), memory::swap()).await;
if let Ok(memory) = memory_result {
dict.insert(
dict.insert_untagged(
"total",
Value::bytes(memory.total().get::<information::byte>()),
UntaggedValue::bytes(memory.total().get::<information::byte>()),
);
dict.insert(
dict.insert_untagged(
"free",
Value::bytes(memory.free().get::<information::byte>()),
UntaggedValue::bytes(memory.free().get::<information::byte>()),
);
}
if let Ok(swap) = swap_result {
dict.insert(
dict.insert_untagged(
"swap total",
Value::bytes(swap.total().get::<information::byte>()),
UntaggedValue::bytes(swap.total().get::<information::byte>()),
);
dict.insert(
dict.insert_untagged(
"swap free",
Value::bytes(swap.free().get::<information::byte>()),
UntaggedValue::bytes(swap.free().get::<information::byte>()),
);
}
dict.into_tagged_value()
dict.into_value()
}
async fn host(tag: Tag) -> Tagged<Value> {
async fn host(tag: Tag) -> Value {
let mut dict = TaggedDictBuilder::with_capacity(&tag, 6);
let (platform_result, uptime_result) =
@ -87,10 +88,13 @@ async fn host(tag: Tag) -> Tagged<Value> {
// OS
if let Ok(platform) = platform_result {
dict.insert("name", Value::string(platform.system()));
dict.insert("release", Value::string(platform.release()));
dict.insert("hostname", Value::string(platform.hostname()));
dict.insert("arch", Value::string(platform.architecture().as_str()));
dict.insert_untagged("name", UntaggedValue::string(platform.system()));
dict.insert_untagged("release", UntaggedValue::string(platform.release()));
dict.insert_untagged("hostname", UntaggedValue::string(platform.hostname()));
dict.insert_untagged(
"arch",
UntaggedValue::string(platform.architecture().as_str()),
);
}
// Uptime
@ -103,12 +107,12 @@ async fn host(tag: Tag) -> Tagged<Value> {
let minutes = (uptime - days * 60 * 60 * 24 - hours * 60 * 60) / 60;
let seconds = uptime % 60;
uptime_dict.insert("days", Value::int(days));
uptime_dict.insert("hours", Value::int(hours));
uptime_dict.insert("mins", Value::int(minutes));
uptime_dict.insert("secs", Value::int(seconds));
uptime_dict.insert_untagged("days", UntaggedValue::int(days));
uptime_dict.insert_untagged("hours", UntaggedValue::int(hours));
uptime_dict.insert_untagged("mins", UntaggedValue::int(minutes));
uptime_dict.insert_untagged("secs", UntaggedValue::int(seconds));
dict.insert_tagged("uptime", uptime_dict);
dict.insert_value("uptime", uptime_dict);
}
// Users
@ -116,63 +120,66 @@ async fn host(tag: Tag) -> Tagged<Value> {
let mut user_vec = vec![];
while let Some(user) = users.next().await {
if let Ok(user) = user {
user_vec.push(Tagged {
item: Value::string(user.username()),
user_vec.push(Value {
value: UntaggedValue::string(user.username()),
tag: tag.clone(),
});
}
}
let user_list = Value::Table(user_vec);
dict.insert("users", user_list);
let user_list = UntaggedValue::Table(user_vec);
dict.insert_untagged("users", user_list);
dict.into_tagged_value()
dict.into_value()
}
async fn disks(tag: Tag) -> Option<Value> {
async fn disks(tag: Tag) -> Option<UntaggedValue> {
let mut output = vec![];
let mut partitions = disk::partitions_physical();
while let Some(part) = partitions.next().await {
if let Ok(part) = part {
let mut dict = TaggedDictBuilder::with_capacity(&tag, 6);
dict.insert(
dict.insert_untagged(
"device",
Value::string(
UntaggedValue::string(
part.device()
.unwrap_or_else(|| OsStr::new("N/A"))
.to_string_lossy(),
),
);
dict.insert("type", Value::string(part.file_system().as_str()));
dict.insert("mount", Value::string(part.mount_point().to_string_lossy()));
dict.insert_untagged("type", UntaggedValue::string(part.file_system().as_str()));
dict.insert_untagged(
"mount",
UntaggedValue::string(part.mount_point().to_string_lossy()),
);
if let Ok(usage) = disk::usage(part.mount_point().to_path_buf()).await {
dict.insert(
dict.insert_untagged(
"total",
Value::bytes(usage.total().get::<information::byte>()),
UntaggedValue::bytes(usage.total().get::<information::byte>()),
);
dict.insert(
dict.insert_untagged(
"used",
Value::bytes(usage.used().get::<information::byte>()),
UntaggedValue::bytes(usage.used().get::<information::byte>()),
);
dict.insert(
dict.insert_untagged(
"free",
Value::bytes(usage.free().get::<information::byte>()),
UntaggedValue::bytes(usage.free().get::<information::byte>()),
);
}
output.push(dict.into_tagged_value());
output.push(dict.into_value());
}
}
if !output.is_empty() {
Some(Value::Table(output))
Some(UntaggedValue::Table(output))
} else {
None
}
}
async fn battery(tag: Tag) -> Option<Value> {
async fn battery(tag: Tag) -> Option<UntaggedValue> {
let mut output = vec![];
if let Ok(manager) = battery::Manager::new() {
@ -181,108 +188,114 @@ async fn battery(tag: Tag) -> Option<Value> {
if let Ok(battery) = battery {
let mut dict = TaggedDictBuilder::new(&tag);
if let Some(vendor) = battery.vendor() {
dict.insert("vendor", Value::string(vendor));
dict.insert_untagged("vendor", UntaggedValue::string(vendor));
}
if let Some(model) = battery.model() {
dict.insert("model", Value::string(model));
dict.insert_untagged("model", UntaggedValue::string(model));
}
if let Some(cycles) = battery.cycle_count() {
dict.insert("cycles", Value::int(cycles));
dict.insert_untagged("cycles", UntaggedValue::int(cycles));
}
if let Some(time_to_full) = battery.time_to_full() {
dict.insert(
dict.insert_untagged(
"mins to full",
Value::number(time_to_full.get::<battery::units::time::minute>()),
UntaggedValue::number(
time_to_full.get::<battery::units::time::minute>(),
),
);
}
if let Some(time_to_empty) = battery.time_to_empty() {
dict.insert(
dict.insert_untagged(
"mins to empty",
Value::number(time_to_empty.get::<battery::units::time::minute>()),
UntaggedValue::number(
time_to_empty.get::<battery::units::time::minute>(),
),
);
}
output.push(dict.into_tagged_value());
output.push(dict.into_value());
}
}
}
}
if !output.is_empty() {
Some(Value::Table(output))
Some(UntaggedValue::Table(output))
} else {
None
}
}
async fn temp(tag: Tag) -> Option<Value> {
async fn temp(tag: Tag) -> Option<UntaggedValue> {
let mut output = vec![];
let mut sensors = sensors::temperatures();
while let Some(sensor) = sensors.next().await {
if let Ok(sensor) = sensor {
let mut dict = TaggedDictBuilder::new(&tag);
dict.insert("unit", Value::string(sensor.unit()));
dict.insert_untagged("unit", UntaggedValue::string(sensor.unit()));
if let Some(label) = sensor.label() {
dict.insert("label", Value::string(label));
dict.insert_untagged("label", UntaggedValue::string(label));
}
dict.insert(
dict.insert_untagged(
"temp",
Value::number(
UntaggedValue::number(
sensor
.current()
.get::<thermodynamic_temperature::degree_celsius>(),
),
);
if let Some(high) = sensor.high() {
dict.insert(
dict.insert_untagged(
"high",
Value::number(high.get::<thermodynamic_temperature::degree_celsius>()),
UntaggedValue::number(high.get::<thermodynamic_temperature::degree_celsius>()),
);
}
if let Some(critical) = sensor.critical() {
dict.insert(
dict.insert_untagged(
"critical",
Value::number(critical.get::<thermodynamic_temperature::degree_celsius>()),
UntaggedValue::number(
critical.get::<thermodynamic_temperature::degree_celsius>(),
),
);
}
output.push(dict.into_tagged_value());
output.push(dict.into_value());
}
}
if !output.is_empty() {
Some(Value::Table(output))
Some(UntaggedValue::Table(output))
} else {
None
}
}
async fn net(tag: Tag) -> Option<Value> {
async fn net(tag: Tag) -> Option<UntaggedValue> {
let mut output = vec![];
let mut io_counters = net::io_counters();
while let Some(nic) = io_counters.next().await {
if let Ok(nic) = nic {
let mut network_idx = TaggedDictBuilder::with_capacity(&tag, 3);
network_idx.insert("name", Value::string(nic.interface()));
network_idx.insert(
network_idx.insert_untagged("name", UntaggedValue::string(nic.interface()));
network_idx.insert_untagged(
"sent",
Value::bytes(nic.bytes_sent().get::<information::byte>()),
UntaggedValue::bytes(nic.bytes_sent().get::<information::byte>()),
);
network_idx.insert(
network_idx.insert_untagged(
"recv",
Value::bytes(nic.bytes_recv().get::<information::byte>()),
UntaggedValue::bytes(nic.bytes_recv().get::<information::byte>()),
);
output.push(network_idx.into_tagged_value());
output.push(network_idx.into_value());
}
}
if !output.is_empty() {
Some(Value::Table(output))
Some(UntaggedValue::Table(output))
} else {
None
}
}
async fn sysinfo(tag: Tag) -> Vec<Tagged<Value>> {
async fn sysinfo(tag: Tag) -> Vec<Value> {
let mut sysinfo = TaggedDictBuilder::with_capacity(&tag, 7);
let (host, cpu, disks, memory, temp) = futures::future::join5(
@ -295,25 +308,25 @@ async fn sysinfo(tag: Tag) -> Vec<Tagged<Value>> {
.await;
let (net, battery) = futures::future::join(net(tag.clone()), battery(tag.clone())).await;
sysinfo.insert_tagged("host", host);
sysinfo.insert_value("host", host);
if let Some(cpu) = cpu {
sysinfo.insert_tagged("cpu", cpu);
sysinfo.insert_value("cpu", cpu);
}
if let Some(disks) = disks {
sysinfo.insert("disks", disks);
sysinfo.insert_untagged("disks", disks);
}
sysinfo.insert_tagged("mem", memory);
sysinfo.insert_value("mem", memory);
if let Some(temp) = temp {
sysinfo.insert("temp", temp);
sysinfo.insert_untagged("temp", temp);
}
if let Some(net) = net {
sysinfo.insert("net", net);
sysinfo.insert_untagged("net", net);
}
if let Some(battery) = battery {
sysinfo.insert("battery", battery);
sysinfo.insert_untagged("battery", battery);
}
vec![sysinfo.into_tagged_value()]
vec![sysinfo.into_value()]
}
impl Plugin for Sys {
@ -330,7 +343,7 @@ impl Plugin for Sys {
.collect())
}
fn filter(&mut self, _: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
fn filter(&mut self, _: Value) -> Result<Vec<ReturnValue>, ShellError> {
Ok(vec![])
}
}

View File

@ -1,9 +1,9 @@
use crossterm::{cursor, terminal, RawScreen};
use crossterm::{InputEvent, KeyEvent};
use nu::{
outln, serve_plugin, AnchorLocation, CallInfo, Plugin, Primitive, ShellError, Signature,
Tagged, Value,
outln, serve_plugin, CallInfo, Plugin, Primitive, ShellError, Signature, UntaggedValue, Value,
};
use nu_source::AnchorLocation;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, ThemeSet};
@ -30,7 +30,7 @@ impl Plugin for TextView {
Ok(Signature::build("textview").desc("Autoview of text data."))
}
fn sink(&mut self, _call_info: CallInfo, input: Vec<Tagged<Value>>) {
fn sink(&mut self, _call_info: CallInfo, input: Vec<Value>) {
view_text_value(&input[0]);
}
}
@ -216,10 +216,10 @@ fn scroll_view(s: &str) {
scroll_view_lines_if_needed(v, false);
}
fn view_text_value(value: &Tagged<Value>) {
fn view_text_value(value: &Value) {
let value_anchor = value.anchor();
match value.item {
Value::Primitive(Primitive::String(ref s)) => {
match &value.value {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
if let Some(source) = value_anchor {
let extension: Option<String> = match source {
AnchorLocation::File(file) => {

View File

@ -14,23 +14,23 @@ pub struct TreeView {
impl TreeView {
fn from_value_helper(value: &Value, mut builder: &mut TreeBuilder) {
match value {
Value::Primitive(p) => {
UntaggedValue::Primitive(p) => {
let _ = builder.add_empty_child(p.format(None));
}
Value::Row(o) => {
UntaggedValue::Row(o) => {
for (k, v) in o.entries.iter() {
builder = builder.begin_child(k.clone());
Self::from_value_helper(v, builder);
builder = builder.end_child();
}
}
Value::Table(l) => {
UntaggedValue::Table(l) => {
for elem in l.iter() {
Self::from_value_helper(elem, builder);
}
}
Value::Block(_) => {}
Value::Binary(_) => {}
UntaggedValue::Block(_) => {}
UntaggedValue::Binary(_) => {}
}
}
@ -82,7 +82,7 @@ impl Plugin for TreeViewer {
Ok(Signature::build("tree").desc("View the contents of the pipeline as a tree."))
}
fn sink(&mut self, _call_info: CallInfo, input: Vec<Tagged<Value>>) {
fn sink(&mut self, _call_info: CallInfo, input: Vec<Value>) {
if input.len() > 0 {
for i in input.iter() {
let view = TreeView::from_value(&i);