forked from extern/nushell
Tests pass
This commit is contained in:
parent
70f9e355fd
commit
7c2a1c619e
@ -181,14 +181,11 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||||||
command("to-toml", Box::new(to_toml::to_toml)),
|
command("to-toml", Box::new(to_toml::to_toml)),
|
||||||
command("sort-by", Box::new(sort_by::sort_by)),
|
command("sort-by", Box::new(sort_by::sort_by)),
|
||||||
command("sort-by", Box::new(sort_by::sort_by)),
|
command("sort-by", Box::new(sort_by::sort_by)),
|
||||||
command("inc", |x| plugin::plugin("inc".into(), x)),
|
|
||||||
command("sum", |x| plugin::plugin("sum".into(), x)),
|
|
||||||
Arc::new(Open),
|
Arc::new(Open),
|
||||||
Arc::new(Where),
|
Arc::new(Where),
|
||||||
Arc::new(Config),
|
Arc::new(Config),
|
||||||
Arc::new(SkipWhile),
|
Arc::new(SkipWhile),
|
||||||
Arc::new(Enter),
|
Arc::new(Enter),
|
||||||
Arc::new(Skip),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
context.add_sinks(vec![
|
context.add_sinks(vec![
|
||||||
|
@ -44,6 +44,5 @@ crate use command::command;
|
|||||||
crate use config::Config;
|
crate use config::Config;
|
||||||
crate use enter::Enter;
|
crate use enter::Enter;
|
||||||
crate use open::Open;
|
crate use open::Open;
|
||||||
crate use skip::Skip;
|
|
||||||
crate use skip_while::SkipWhile;
|
crate use skip_while::SkipWhile;
|
||||||
crate use where_::Where;
|
crate use where_::Where;
|
||||||
|
@ -5,7 +5,11 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
|
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||||
if args.input.len() > 0 {
|
if args.input.len() > 0 {
|
||||||
if let Value::Binary(_) = args.input[0] {
|
if let Spanned {
|
||||||
|
item: Value::Binary(_),
|
||||||
|
..
|
||||||
|
} = args.input[0]
|
||||||
|
{
|
||||||
args.ctx.get_sink("binaryview").run(args)?;
|
args.ctx.get_sink("binaryview").run(args)?;
|
||||||
} else if equal_shapes(&args.input) {
|
} else if equal_shapes(&args.input) {
|
||||||
args.ctx.get_sink("table").run(args)?;
|
args.ctx.get_sink("table").run(args)?;
|
||||||
|
@ -12,8 +12,12 @@ impl Command for Enter {
|
|||||||
fn config(&self) -> CommandConfig {
|
fn config(&self) -> CommandConfig {
|
||||||
CommandConfig {
|
CommandConfig {
|
||||||
name: self.name().to_string(),
|
name: self.name().to_string(),
|
||||||
positional: vec![PositionalType::mandatory("path", "Block")],
|
positional: vec![PositionalType::mandatory_block("path")],
|
||||||
rest_positional: false,
|
rest_positional: false,
|
||||||
|
can_load: vec![],
|
||||||
|
can_save: vec![],
|
||||||
|
is_filter: false,
|
||||||
|
is_sink: false,
|
||||||
named: indexmap::IndexMap::new(),
|
named: indexmap::IndexMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,9 +93,15 @@ pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match contents {
|
||||||
|
Value::Primitive(Primitive::String(string)) => {
|
||||||
stream.push_back(Ok(ReturnSuccess::Action(CommandAction::Enter(
|
stream.push_back(Ok(ReturnSuccess::Action(CommandAction::Enter(
|
||||||
parse_as_value(file_extension, contents, contents_span, span)?,
|
parse_as_value(file_extension, string, contents_span, span)?,
|
||||||
))));
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
|
||||||
|
};
|
||||||
|
|
||||||
Ok(stream.into())
|
Ok(stream.into())
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>)
|
|||||||
serde_hjson::Value::Object(o) => {
|
serde_hjson::Value::Object(o) => {
|
||||||
let mut collected = SpannedDictBuilder::new(span);
|
let mut collected = SpannedDictBuilder::new(span);
|
||||||
for (k, v) in o.iter() {
|
for (k, v) in o.iter() {
|
||||||
collected.add(k.clone(), convert_json_value_to_nu_value(v, span));
|
collected.insert_spanned(k.clone(), convert_json_value_to_nu_value(v, span));
|
||||||
}
|
}
|
||||||
|
|
||||||
collected.into_spanned_value()
|
collected.into_spanned_value()
|
||||||
|
@ -25,7 +25,7 @@ fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spa
|
|||||||
let mut collected = SpannedDictBuilder::new(span);
|
let mut collected = SpannedDictBuilder::new(span);
|
||||||
|
|
||||||
for (k, v) in t.iter() {
|
for (k, v) in t.iter() {
|
||||||
collected.add(k.clone(), convert_toml_value_to_nu_value(v, span));
|
collected.insert_spanned(k.clone(), convert_toml_value_to_nu_value(v, span));
|
||||||
}
|
}
|
||||||
|
|
||||||
collected.into_spanned_value()
|
collected.into_spanned_value()
|
||||||
|
@ -32,8 +32,8 @@ fn from_node_to_value<'a, 'd>(
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut collected = Dictionary::default();
|
let mut collected = SpannedDictBuilder::new(span);
|
||||||
collected.add(name.clone(), Value::List(children_values).spanned(span));
|
collected.insert(name.clone(), Value::List(children_values));
|
||||||
|
|
||||||
collected.into_spanned_value()
|
collected.into_spanned_value()
|
||||||
} else if n.is_comment() {
|
} else if n.is_comment() {
|
||||||
|
@ -26,7 +26,8 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>)
|
|||||||
for (k, v) in t.iter() {
|
for (k, v) in t.iter() {
|
||||||
match k {
|
match k {
|
||||||
serde_yaml::Value::String(k) => {
|
serde_yaml::Value::String(k) => {
|
||||||
collected.add(k.clone(), convert_yaml_value_to_nu_value(v, span));
|
collected
|
||||||
|
.insert_spanned(k.clone(), convert_yaml_value_to_nu_value(v, span));
|
||||||
}
|
}
|
||||||
_ => unimplemented!("Unknown key type"),
|
_ => unimplemented!("Unknown key type"),
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,11 @@ macro_rules! command {
|
|||||||
name: self.name().to_string(),
|
name: self.name().to_string(),
|
||||||
positional: vec![$($mandatory_positional)*],
|
positional: vec![$($mandatory_positional)*],
|
||||||
rest_positional: false,
|
rest_positional: false,
|
||||||
|
can_load: vec![],
|
||||||
|
can_save: vec![],
|
||||||
|
is_filter: false,
|
||||||
|
is_sink: false,
|
||||||
|
|
||||||
named: {
|
named: {
|
||||||
use $crate::parser::registry::NamedType;
|
use $crate::parser::registry::NamedType;
|
||||||
|
|
||||||
|
@ -61,12 +61,18 @@ command! {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
match contents {
|
||||||
|
Value::Primitive(Primitive::String(string)) =>
|
||||||
stream.push_back(ReturnSuccess::value(parse_as_value(
|
stream.push_back(ReturnSuccess::value(parse_as_value(
|
||||||
file_extension,
|
file_extension,
|
||||||
contents,
|
string,
|
||||||
contents_span,
|
contents_span,
|
||||||
span,
|
span,
|
||||||
)?));
|
)?)
|
||||||
|
),
|
||||||
|
|
||||||
|
other => stream.push_back(ReturnSuccess::value(other.spanned(span))),
|
||||||
|
};
|
||||||
|
|
||||||
stream
|
stream
|
||||||
}
|
}
|
||||||
@ -76,7 +82,7 @@ pub fn fetch(
|
|||||||
cwd: &PathBuf,
|
cwd: &PathBuf,
|
||||||
location: &str,
|
location: &str,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(Option<String>, String, Span), ShellError> {
|
) -> Result<(Option<String>, Value, Span), ShellError> {
|
||||||
let mut cwd = cwd.clone();
|
let mut cwd = cwd.clone();
|
||||||
if location.starts_with("http:") || location.starts_with("https:") {
|
if location.starts_with("http:") || location.starts_with("https:") {
|
||||||
let response = reqwest::get(location);
|
let response = reqwest::get(location);
|
||||||
@ -107,7 +113,7 @@ pub fn fetch(
|
|||||||
None => path_extension,
|
None => path_extension,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((extension, s, span))
|
Ok((extension, Value::string(s), span))
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
@ -132,10 +138,10 @@ pub fn fetch(
|
|||||||
Ok(s) => Ok((
|
Ok(s) => Ok((
|
||||||
cwd.extension()
|
cwd.extension()
|
||||||
.map(|name| name.to_string_lossy().to_string()),
|
.map(|name| name.to_string_lossy().to_string()),
|
||||||
s,
|
Value::string(s),
|
||||||
span,
|
span,
|
||||||
)),
|
)),
|
||||||
Err(_) => Ok((None, Value::Binary(bytes))),
|
Err(_) => Ok((None, Value::Binary(bytes), span)),
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
return Err(ShellError::labeled_error(
|
return Err(ShellError::labeled_error(
|
||||||
|
@ -55,6 +55,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
|
|||||||
|
|
||||||
let stream = args
|
let stream = args
|
||||||
.input
|
.input
|
||||||
|
.values
|
||||||
.chain(eos)
|
.chain(eos)
|
||||||
.map(move |v| match v {
|
.map(move |v| match v {
|
||||||
Spanned {
|
Spanned {
|
||||||
@ -90,7 +91,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
|
|||||||
Ok(params) => params,
|
Ok(params) => params,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let mut result = VecDeque::new();
|
let mut result = VecDeque::new();
|
||||||
result.push_back(ReturnValue::Value(Value::Error(Box::new(e))));
|
result.push_back(ReturnValue::Err(e));
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@ impl Command for SkipWhile {
|
|||||||
fn config(&self) -> CommandConfig {
|
fn config(&self) -> CommandConfig {
|
||||||
CommandConfig {
|
CommandConfig {
|
||||||
name: self.name().to_string(),
|
name: self.name().to_string(),
|
||||||
positional: vec![PositionalType::mandatory("condition", "Block")],
|
positional: vec![PositionalType::mandatory_block("condition")],
|
||||||
rest_positional: false,
|
rest_positional: false,
|
||||||
named: indexmap::IndexMap::new(),
|
named: indexmap::IndexMap::new(),
|
||||||
is_filter: true,
|
is_filter: true,
|
||||||
|
@ -22,7 +22,6 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value {
|
|||||||
Value::List(l) => {
|
Value::List(l) => {
|
||||||
serde_json::Value::Array(l.iter().map(|x| value_to_json_value(x)).collect())
|
serde_json::Value::Array(l.iter().map(|x| value_to_json_value(x)).collect())
|
||||||
}
|
}
|
||||||
Value::Error(e) => serde_json::Value::String(e.to_string()),
|
|
||||||
Value::Block(_) => serde_json::Value::Null,
|
Value::Block(_) => serde_json::Value::Null,
|
||||||
Value::Binary(b) => serde_json::Value::Array(
|
Value::Binary(b) => serde_json::Value::Array(
|
||||||
b.iter()
|
b.iter()
|
||||||
|
@ -16,7 +16,6 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
|||||||
|
|
||||||
Value::Filesystem => toml::Value::String("<Filesystem>".to_string()),
|
Value::Filesystem => toml::Value::String("<Filesystem>".to_string()),
|
||||||
Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()),
|
Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()),
|
||||||
Value::Error(e) => toml::Value::String(e.to_string()),
|
|
||||||
Value::Block(_) => toml::Value::String("<Block>".to_string()),
|
Value::Block(_) => toml::Value::String("<Block>".to_string()),
|
||||||
Value::Binary(b) => {
|
Value::Binary(b) => {
|
||||||
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
toml::Value::Array(b.iter().map(|x| toml::Value::Integer(*x as i64)).collect())
|
||||||
@ -38,7 +37,7 @@ pub fn to_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||||||
Ok(out
|
Ok(out
|
||||||
.values
|
.values
|
||||||
.map(move |a| {
|
.map(move |a| {
|
||||||
match toml::to_string(&a) {
|
match toml::to_string(&value_to_toml_value(&a)) {
|
||||||
Ok(val) => {
|
Ok(val) => {
|
||||||
return ReturnSuccess::value(
|
return ReturnSuccess::value(
|
||||||
Value::Primitive(Primitive::String(val)).spanned(name_span),
|
Value::Primitive(Primitive::String(val)).spanned(name_span),
|
||||||
@ -46,7 +45,7 @@ pub fn to_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Err(err) => Err(ShellError::type_error(
|
Err(err) => Err(ShellError::type_error(
|
||||||
"String",
|
"serializable to toml",
|
||||||
format!("{:?} - {:?}", a.type_name(), err).spanned(name_span),
|
format!("{:?} - {:?}", a.type_name(), err).spanned(name_span),
|
||||||
)), // toml::Value::String(String) => {
|
)), // toml::Value::String(String) => {
|
||||||
// return ReturnSuccess::value(
|
// return ReturnSuccess::value(
|
||||||
|
@ -36,11 +36,6 @@ impl RenderView for GenericView<'value> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
Value::Error(e) => {
|
|
||||||
host.stdout(&format!("{:?}", e));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
Value::Binary(_) => {
|
Value::Binary(_) => {
|
||||||
host.stdout("<Binary>");
|
host.stdout("<Binary>");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -299,10 +299,6 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn debug(&'a self) -> ValueDebug<'a> {
|
|
||||||
ValueDebug { value: self }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn data_descriptors(&self) -> Vec<String> {
|
pub fn data_descriptors(&self) -> Vec<String> {
|
||||||
match self {
|
match self {
|
||||||
Value::Primitive(_) => vec![],
|
Value::Primitive(_) => vec![],
|
||||||
@ -314,7 +310,6 @@ impl Value {
|
|||||||
.collect(),
|
.collect(),
|
||||||
Value::Block(_) => vec![],
|
Value::Block(_) => vec![],
|
||||||
Value::List(_) => vec![],
|
Value::List(_) => vec![],
|
||||||
Value::Error(_) => vec![],
|
|
||||||
Value::Filesystem => vec![],
|
Value::Filesystem => vec![],
|
||||||
Value::Binary(_) => vec![],
|
Value::Binary(_) => vec![],
|
||||||
}
|
}
|
||||||
@ -356,7 +351,6 @@ impl Value {
|
|||||||
Value::Object(o) => o.get_data(desc),
|
Value::Object(o) => o.get_data(desc),
|
||||||
Value::Block(_) => MaybeOwned::Owned(Value::nothing()),
|
Value::Block(_) => MaybeOwned::Owned(Value::nothing()),
|
||||||
Value::List(_) => MaybeOwned::Owned(Value::nothing()),
|
Value::List(_) => MaybeOwned::Owned(Value::nothing()),
|
||||||
Value::Error(e) => MaybeOwned::Owned(Value::string(&format!("{:#?}", e))),
|
|
||||||
Value::Binary(_) => MaybeOwned::Owned(Value::nothing()),
|
Value::Binary(_) => MaybeOwned::Owned(Value::nothing()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -512,7 +506,7 @@ crate fn select_fields(obj: &Value, fields: &[String], span: impl Into<Span>) ->
|
|||||||
let descs = obj.data_descriptors();
|
let descs = obj.data_descriptors();
|
||||||
|
|
||||||
for field in fields {
|
for field in fields {
|
||||||
match descs.iter().find(|d| d.name.is_string(field)) {
|
match descs.iter().find(|d| *d == field) {
|
||||||
None => out.insert(field, Value::nothing()),
|
None => out.insert(field, Value::nothing()),
|
||||||
Some(desc) => out.insert(desc.clone(), obj.get_data(desc).borrow().clone()),
|
Some(desc) => out.insert(desc.clone(), obj.get_data(desc).borrow().clone()),
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ impl Dictionary {
|
|||||||
let mut out = Dictionary::default();
|
let mut out = Dictionary::default();
|
||||||
|
|
||||||
for (key, value) in self.entries.iter() {
|
for (key, value) in self.entries.iter() {
|
||||||
out.add(key.clone(), value.copy());
|
out.add(key.clone(), value.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
out
|
out
|
||||||
@ -150,7 +150,7 @@ impl From<SpannedListBuilder> for Spanned<Value> {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SpannedDictBuilder {
|
pub struct SpannedDictBuilder {
|
||||||
span: Span,
|
span: Span,
|
||||||
dict: IndexMap<DataDescriptor, Spanned<Value>>,
|
dict: IndexMap<String, Spanned<Value>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SpannedDictBuilder {
|
impl SpannedDictBuilder {
|
||||||
@ -161,16 +161,12 @@ impl SpannedDictBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, key: impl Into<DataDescriptor>, value: impl Into<Value>) {
|
pub fn insert(&mut self, key: impl Into<String>, value: impl Into<Value>) {
|
||||||
self.dict
|
self.dict
|
||||||
.insert(key.into(), value.into().spanned(self.span));
|
.insert(key.into(), value.into().spanned(self.span));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_spanned(
|
pub fn insert_spanned(&mut self, key: impl Into<String>, value: impl Into<Spanned<Value>>) {
|
||||||
&mut self,
|
|
||||||
key: impl Into<DataDescriptor>,
|
|
||||||
value: impl Into<Spanned<Value>>,
|
|
||||||
) {
|
|
||||||
self.dict.insert(key.into(), value.into());
|
self.dict.insert(key.into(), value.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,22 +4,15 @@ use getset::Getters;
|
|||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
|
|
||||||
#[derive(new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Deserialize, Hash, Getters)]
|
#[derive(
|
||||||
|
new, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, Getters,
|
||||||
|
)]
|
||||||
#[get = "crate"]
|
#[get = "crate"]
|
||||||
pub struct Spanned<T> {
|
pub struct Spanned<T> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub item: T,
|
pub item: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Serialize> Serialize for Spanned<T> {
|
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
||||||
where
|
|
||||||
S: Serializer,
|
|
||||||
{
|
|
||||||
self.item.serialize(serializer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Spanned<T> {
|
impl<T> Spanned<T> {
|
||||||
pub fn spanned(self, span: impl Into<Span>) -> Spanned<T> {
|
pub fn spanned(self, span: impl Into<Span>) -> Spanned<T> {
|
||||||
Spanned::from_item(self.item, span.into())
|
Spanned::from_item(self.item, span.into())
|
||||||
|
@ -40,18 +40,19 @@ pub enum PositionalType {
|
|||||||
Optional(String, PositionalValue),
|
Optional(String, PositionalValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum PositionalValue {
|
pub enum PositionalValue {
|
||||||
Value,
|
Value,
|
||||||
Block,
|
Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PositionalType {
|
impl PositionalType {
|
||||||
crate fn mandatory(name: &str, kind: &str) -> PositionalType {
|
pub fn mandatory(name: &str) -> PositionalType {
|
||||||
match kind {
|
PositionalType::Mandatory(name.to_string(), PositionalValue::Value)
|
||||||
"Block" => PositionalType::Mandatory(name.to_string(), PositionalValue::Block),
|
|
||||||
_ => PositionalType::Mandatory(name.to_string(), PositionalValue::Value),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn mandatory_block(name: &str) -> PositionalType {
|
||||||
|
PositionalType::Mandatory(name.to_string(), PositionalValue::Block)
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn to_coerce_hint(&self) -> Option<ExpressionKindHint> {
|
crate fn to_coerce_hint(&self) -> Option<ExpressionKindHint> {
|
||||||
@ -76,7 +77,7 @@ impl PositionalType {
|
|||||||
#[get = "crate"]
|
#[get = "crate"]
|
||||||
pub struct CommandConfig {
|
pub struct CommandConfig {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
crate positional: Vec<PositionalType>,
|
pub positional: Vec<PositionalType>,
|
||||||
pub rest_positional: bool,
|
pub rest_positional: bool,
|
||||||
pub named: IndexMap<String, NamedType>,
|
pub named: IndexMap<String, NamedType>,
|
||||||
pub is_filter: bool,
|
pub is_filter: bool,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Args, CommandConfig, ReturnValue, ShellError, Value};
|
use crate::{Args, CommandConfig, ReturnValue, ShellError, Spanned, Value};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
@ -11,11 +11,11 @@ pub trait Plugin {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
Err(ShellError::string("`filter` not implemented in plugin"))
|
Err(ShellError::string("`filter` not implemented in plugin"))
|
||||||
}
|
}
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn sink(&mut self, args: Args, input: Vec<Value>) {}
|
fn sink(&mut self, args: Args, input: Vec<Spanned<Value>>) {}
|
||||||
|
|
||||||
fn quit(&mut self) {
|
fn quit(&mut self) {
|
||||||
return;
|
return;
|
||||||
@ -127,7 +127,7 @@ fn send_response<T: Serialize>(result: T) {
|
|||||||
pub enum NuCommand {
|
pub enum NuCommand {
|
||||||
config,
|
config,
|
||||||
begin_filter { params: Args },
|
begin_filter { params: Args },
|
||||||
filter { params: Value },
|
filter { params: Spanned<Value> },
|
||||||
sink { params: (Args, Vec<Value>) },
|
sink { params: (Args, Vec<Spanned<Value>>) },
|
||||||
quit,
|
quit,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crossterm::{cursor, terminal, Attribute, RawScreen};
|
use crossterm::{cursor, terminal, Attribute, RawScreen};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Value};
|
use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Spanned, Value};
|
||||||
use pretty_hex::*;
|
use pretty_hex::*;
|
||||||
|
|
||||||
struct BinaryView;
|
struct BinaryView;
|
||||||
@ -15,8 +15,7 @@ impl Plugin for BinaryView {
|
|||||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||||
Ok(CommandConfig {
|
Ok(CommandConfig {
|
||||||
name: "binaryview".to_string(),
|
name: "binaryview".to_string(),
|
||||||
mandatory_positional: vec![],
|
positional: vec![],
|
||||||
optional_positional: vec![],
|
|
||||||
can_load: vec![],
|
can_load: vec![],
|
||||||
can_save: vec![],
|
can_save: vec![],
|
||||||
is_filter: false,
|
is_filter: false,
|
||||||
@ -26,10 +25,13 @@ impl Plugin for BinaryView {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink(&mut self, _args: Args, input: Vec<Value>) {
|
fn sink(&mut self, _args: Args, input: Vec<Spanned<Value>>) {
|
||||||
for v in input {
|
for v in input {
|
||||||
match v {
|
match v {
|
||||||
Value::Binary(b) => {
|
Spanned {
|
||||||
|
item: Value::Binary(b),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
let _ = view_binary(&b);
|
let _ = view_binary(&b);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu::{
|
use nu::{
|
||||||
serve_plugin, Args, CommandConfig, Plugin, PositionalType, Primitive, ReturnValue, ShellError,
|
serve_plugin, Args, CommandConfig, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||||
Spanned, Value,
|
ReturnValue, ShellError, Spanned, SpannedItem, Value,
|
||||||
};
|
};
|
||||||
use nu::{Primitive, ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
struct Inc {
|
struct Inc {
|
||||||
inc_by: i64,
|
inc_by: i64,
|
||||||
@ -16,87 +13,47 @@ impl Inc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_response<T: Serialize>(result: Vec<T>) {
|
impl Plugin for Inc {
|
||||||
let response = JsonRpc::new("response", result);
|
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||||
let response_raw = serde_json::to_string(&response).unwrap();
|
Ok(CommandConfig {
|
||||||
println!("{}", response_raw);
|
name: "inc".to_string(),
|
||||||
}
|
positional: vec![PositionalType::mandatory("Increment")],
|
||||||
|
can_load: vec![],
|
||||||
fn send_error(error: ShellError) {
|
can_save: vec![],
|
||||||
let message: ReturnValue = Err(error);
|
is_filter: true,
|
||||||
send_response(vec![message])
|
is_sink: false,
|
||||||
}
|
named: IndexMap::new(),
|
||||||
|
rest_positional: true,
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
})
|
||||||
#[serde(tag = "method")]
|
}
|
||||||
#[allow(non_camel_case_types)]
|
fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> {
|
||||||
pub enum NuCommand {
|
if let Some(args) = args.positional {
|
||||||
init { params: Vec<Spanned<Value>> },
|
for arg in args {
|
||||||
filter { params: Spanned<Value> },
|
match arg {
|
||||||
quit,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mut inc_by = 1;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut input = String::new();
|
|
||||||
match io::stdin().read_line(&mut input) {
|
|
||||||
Ok(_) => {
|
|
||||||
let command = serde_json::from_str::<NuCommand>(&input);
|
|
||||||
|
|
||||||
match command {
|
|
||||||
Ok(NuCommand::init { params }) => {
|
|
||||||
for param in params {
|
|
||||||
match param {
|
|
||||||
Spanned {
|
Spanned {
|
||||||
item: Value::Primitive(Primitive::Int(i)),
|
item: Value::Primitive(Primitive::Int(i)),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
inc_by = i;
|
self.inc_by = i;
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
send_error(ShellError::string("Unrecognized type in params"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(NuCommand::filter { params }) => match params {
|
|
||||||
Spanned {
|
|
||||||
item: Value::Primitive(Primitive::Int(i)),
|
|
||||||
span,
|
|
||||||
} => {
|
|
||||||
send_response(vec![ReturnSuccess::value(
|
|
||||||
Value::int(i + inc_by).spanned(span),
|
|
||||||
)]);
|
|
||||||
}
|
|
||||||
Spanned {
|
|
||||||
item: Value::Primitive(Primitive::Bytes(b)),
|
|
||||||
span,
|
|
||||||
} => {
|
|
||||||
send_response(vec![ReturnSuccess::value(
|
|
||||||
Value::bytes(b + inc_by as u128).spanned(span),
|
|
||||||
)]);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
send_error(ShellError::string("Unrecognized type in stream"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Ok(NuCommand::quit) => {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
send_error(ShellError::string("Unrecognized type in stream"));
|
|
||||||
}
|
}
|
||||||
_ => return Err(ShellError::string("Unrecognized type in params")),
|
_ => return Err(ShellError::string("Unrecognized type in params")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
|
||||||
send_error(ShellError::string("Unrecognized type in stream"));
|
|
||||||
}
|
}
|
||||||
Value::Primitive(Primitive::Bytes(b)) => Ok(vec![ReturnValue::Value(Value::bytes(
|
|
||||||
b + self.inc_by as u64,
|
Ok(())
|
||||||
))]),
|
}
|
||||||
|
|
||||||
|
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
|
let span = input.span;
|
||||||
|
|
||||||
|
match input.item {
|
||||||
|
Value::Primitive(Primitive::Int(i)) => Ok(vec![ReturnSuccess::value(
|
||||||
|
Value::int(i + self.inc_by).spanned(span),
|
||||||
|
)]),
|
||||||
|
Value::Primitive(Primitive::Bytes(b)) => Ok(vec![ReturnSuccess::value(
|
||||||
|
Value::bytes(b + self.inc_by as u64).spanned(span),
|
||||||
|
)]),
|
||||||
x => Err(ShellError::string(format!(
|
x => Err(ShellError::string(format!(
|
||||||
"Unrecognized type in stream: {:?}",
|
"Unrecognized type in stream: {:?}",
|
||||||
x
|
x
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu::{
|
use nu::{
|
||||||
serve_plugin, Args, CommandConfig, Plugin, Primitive, ReturnValue, ShellError, Spanned, Value,
|
serve_plugin, Args, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
|
||||||
|
Spanned, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NewSkip {
|
struct NewSkip {
|
||||||
@ -16,8 +17,7 @@ impl Plugin for NewSkip {
|
|||||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||||
Ok(CommandConfig {
|
Ok(CommandConfig {
|
||||||
name: "skip".to_string(),
|
name: "skip".to_string(),
|
||||||
mandatory_positional: vec![],
|
positional: vec![],
|
||||||
optional_positional: vec![],
|
|
||||||
can_load: vec![],
|
can_load: vec![],
|
||||||
can_save: vec![],
|
can_save: vec![],
|
||||||
is_filter: true,
|
is_filter: true,
|
||||||
@ -44,9 +44,9 @@ impl Plugin for NewSkip {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
|
fn filter(&mut self, input: Spanned<Value>) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
if self.skip_amount == 0 {
|
if self.skip_amount == 0 {
|
||||||
Ok(vec![ReturnValue::Value(input)])
|
Ok(vec![ReturnSuccess::value(input)])
|
||||||
} else {
|
} else {
|
||||||
self.skip_amount -= 1;
|
self.skip_amount -= 1;
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Value};
|
use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Spanned, Value};
|
||||||
use ptree::item::StringItem;
|
use ptree::item::StringItem;
|
||||||
use ptree::output::print_tree_with;
|
use ptree::output::print_tree_with;
|
||||||
use ptree::print_config::PrintConfig;
|
use ptree::print_config::PrintConfig;
|
||||||
@ -31,7 +31,6 @@ impl TreeView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Block(_) => {}
|
Value::Block(_) => {}
|
||||||
Value::Error(_) => {}
|
|
||||||
Value::Filesystem => {}
|
Value::Filesystem => {}
|
||||||
Value::Binary(_) => {}
|
Value::Binary(_) => {}
|
||||||
}
|
}
|
||||||
@ -85,8 +84,7 @@ impl Plugin for TreeViewer {
|
|||||||
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
fn config(&mut self) -> Result<CommandConfig, ShellError> {
|
||||||
Ok(CommandConfig {
|
Ok(CommandConfig {
|
||||||
name: "tree".to_string(),
|
name: "tree".to_string(),
|
||||||
mandatory_positional: vec![],
|
positional: vec![],
|
||||||
optional_positional: vec![],
|
|
||||||
can_load: vec![],
|
can_load: vec![],
|
||||||
can_save: vec![],
|
can_save: vec![],
|
||||||
is_filter: false,
|
is_filter: false,
|
||||||
@ -96,12 +94,11 @@ impl Plugin for TreeViewer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink(&mut self, _args: Args, input: Vec<Value>) {
|
fn sink(&mut self, _args: Args, input: Vec<Spanned<Value>>) {
|
||||||
if input.len() > 0 {
|
if input.len() > 0 {
|
||||||
for i in input.iter() {
|
for i in input.iter() {
|
||||||
let view = TreeView::from_value(&i);
|
let view = TreeView::from_value(&i);
|
||||||
let _ = view.render_view();
|
let _ = view.render_view();
|
||||||
//handle_unexpected(&mut *host, |host| crate::format::print_view(&view, host));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user