mirror of
https://github.com/nushell/nushell
synced 2024-11-14 17:07:07 +00:00
Introduce CallInfo, which abstracts args, name_span, and source_map
This commit is contained in:
parent
08f6d29b79
commit
15507f00fc
36 changed files with 173 additions and 116 deletions
|
@ -14,7 +14,7 @@ pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
|
|||
{
|
||||
args.ctx.get_sink("binaryview").run(args)?;
|
||||
} else if is_single_text_value(&args.input) {
|
||||
view_text_value(&args.input[0], &args.source_map);
|
||||
view_text_value(&args.input[0], &args.call_info.source_map);
|
||||
} else if equal_shapes(&args.input) {
|
||||
args.ctx.get_sink("table").run(args)?;
|
||||
} else {
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
"Can not change to home directory",
|
||||
"can not go to home",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
))
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,7 +16,7 @@ pub fn clip(args: SinkCommandArgs) -> Result<(), ShellError> {
|
|||
}
|
||||
|
||||
let string = i.as_string().map_err(labelled(
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
"Given non-string data",
|
||||
"expected strings from pipeline",
|
||||
))?;
|
||||
|
|
|
@ -12,49 +12,52 @@ use serde::{Deserialize, Serialize};
|
|||
use std::path::PathBuf;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct CallInfo {
|
||||
pub args: Args,
|
||||
pub source_map: SourceMap,
|
||||
pub name_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Getters)]
|
||||
#[get = "crate"]
|
||||
pub struct CommandArgs {
|
||||
pub host: Arc<Mutex<dyn Host + Send>>,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub name_span: Option<Span>,
|
||||
pub source_map: SourceMap,
|
||||
pub args: Args,
|
||||
pub call_info: CallInfo,
|
||||
pub input: InputStream,
|
||||
}
|
||||
|
||||
impl CommandArgs {
|
||||
pub fn nth(&self, pos: usize) -> Option<&Spanned<Value>> {
|
||||
self.args.nth(pos)
|
||||
self.call_info.args.nth(pos)
|
||||
}
|
||||
|
||||
pub fn positional_iter(&self) -> impl Iterator<Item = &Spanned<Value>> {
|
||||
self.args.positional_iter()
|
||||
self.call_info.args.positional_iter()
|
||||
}
|
||||
|
||||
pub fn expect_nth(&self, pos: usize) -> Result<&Spanned<Value>, ShellError> {
|
||||
self.args.expect_nth(pos)
|
||||
self.call_info.args.expect_nth(pos)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.args.len()
|
||||
self.call_info.args.len()
|
||||
}
|
||||
|
||||
pub fn get(&self, name: &str) -> Option<&Spanned<Value>> {
|
||||
self.args.get(name)
|
||||
self.call_info.args.get(name)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn has(&self, name: &str) -> bool {
|
||||
self.args.has(name)
|
||||
self.call_info.args.has(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SinkCommandArgs {
|
||||
pub ctx: Context,
|
||||
pub name_span: Option<Span>,
|
||||
pub source_map: SourceMap,
|
||||
pub args: Args,
|
||||
pub call_info: CallInfo,
|
||||
pub input: Vec<Spanned<Value>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ impl Command for Config {
|
|||
}
|
||||
|
||||
pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut result = crate::object::config::config(args.name_span)?;
|
||||
let mut result = crate::object::config::config(args.call_info.name_span)?;
|
||||
|
||||
trace!("{:#?}", args.args.positional);
|
||||
trace!("{:#?}", args.args.named);
|
||||
trace!("{:#?}", args.call_info.args.positional);
|
||||
trace!("{:#?}", args.call_info.args.named);
|
||||
|
||||
if let Some(v) = args.get("get") {
|
||||
let key = v.as_string()?;
|
||||
|
@ -95,7 +95,7 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
}
|
||||
|
||||
if args.len() == 0 {
|
||||
return Ok(vec![Value::Object(result.into()).spanned(args.name_span)].into());
|
||||
return Ok(vec![Value::Object(result.into()).spanned(args.call_info.name_span)].into());
|
||||
}
|
||||
|
||||
Err(ShellError::string(format!("Unimplemented")))
|
||||
|
|
|
@ -8,7 +8,7 @@ pub fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
"First requires an amount",
|
||||
"needs parameter",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ pub fn from_csv_string_to_value(
|
|||
s: String,
|
||||
span: impl Into<Span>,
|
||||
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> {
|
||||
|
||||
let mut reader = ReaderBuilder::new().has_headers(false).from_reader(s.as_bytes());
|
||||
let mut reader = ReaderBuilder::new()
|
||||
.has_headers(false)
|
||||
.from_reader(s.as_bytes());
|
||||
let span = span.into();
|
||||
|
||||
let mut fields: VecDeque<String> = VecDeque::new();
|
||||
|
@ -28,9 +29,12 @@ pub fn from_csv_string_to_value(
|
|||
let row_values = row_values?;
|
||||
|
||||
let mut row = SpannedDictBuilder::new(span);
|
||||
|
||||
|
||||
for (idx, entry) in row_values.iter().enumerate() {
|
||||
row.insert_spanned(fields.get(idx).unwrap(), Value::Primitive(Primitive::String(String::from(entry))).spanned(span));
|
||||
row.insert_spanned(
|
||||
fields.get(idx).unwrap(),
|
||||
Value::Primitive(Primitive::String(String::from(entry))).spanned(span),
|
||||
);
|
||||
}
|
||||
|
||||
rows.insert_spanned(row.into_spanned_value());
|
||||
|
@ -45,7 +49,7 @@ pub fn from_csv_string_to_value(
|
|||
|
||||
pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
Ok(out
|
||||
.values
|
||||
|
|
|
@ -39,7 +39,7 @@ pub fn from_ini_string_to_value(
|
|||
|
||||
pub fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| match a.item {
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn from_json_string_to_value(
|
|||
|
||||
pub fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| match a.item {
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn from_toml_string_to_value(
|
|||
|
||||
pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| match a.item {
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn from_xml_string_to_value(
|
|||
|
||||
pub fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| match a.item {
|
||||
|
|
|
@ -50,7 +50,7 @@ pub fn from_yaml_string_to_value(
|
|||
|
||||
pub fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| match a.item {
|
||||
|
|
|
@ -26,7 +26,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
"Get requires a field or field path",
|
||||
"needs parameter",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use log::trace;
|
|||
|
||||
pub fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let input = args.input;
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
let stream = input
|
||||
.values
|
||||
|
|
|
@ -30,7 +30,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
let mut shell_entries = VecDeque::new();
|
||||
|
||||
for entry in entries {
|
||||
let value = dir_entry_dict(&entry?, args.name_span)?;
|
||||
let value = dir_entry_dict(&entry?, args.call_info.name_span)?;
|
||||
shell_entries.push_back(ReturnSuccess::value(value))
|
||||
}
|
||||
Ok(shell_entries.to_output_stream())
|
||||
|
|
|
@ -10,7 +10,7 @@ use uuid::Uuid;
|
|||
|
||||
command! {
|
||||
Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) {
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
let cwd = args
|
||||
.env
|
||||
|
@ -48,7 +48,7 @@ command! {
|
|||
)?)
|
||||
),
|
||||
|
||||
other => stream.push_back(ReturnSuccess::value(other.spanned(span))),
|
||||
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
|
||||
};
|
||||
|
||||
stream
|
||||
|
|
|
@ -7,7 +7,7 @@ pub fn pick(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
"Pick requires fields",
|
||||
"needs parameter",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
|
|||
|
||||
let mut reader = BufReader::new(stdout);
|
||||
|
||||
let request = JsonRpc::new("begin_filter", args.args);
|
||||
let request = JsonRpc::new("begin_filter", args.call_info);
|
||||
let request_raw = serde_json::to_string(&request).unwrap();
|
||||
stdin.write(format!("{}\n", request_raw).as_bytes())?;
|
||||
let mut input = String::new();
|
||||
|
@ -183,7 +183,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
|
|||
|
||||
pub fn sink_plugin(path: String, args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
//use subprocess::Exec;
|
||||
let request = JsonRpc::new("sink", (args.args, args.input));
|
||||
let request = JsonRpc::new("sink", (args.call_info, args.input));
|
||||
let request_raw = serde_json::to_string(&request).unwrap();
|
||||
let mut tmpfile = tempfile::NamedTempFile::new()?;
|
||||
let _ = writeln!(tmpfile, "{}", request_raw);
|
||||
|
|
|
@ -10,7 +10,7 @@ pub fn ps(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
|
||||
let list = list
|
||||
.into_iter()
|
||||
.map(|(_, process)| process_dict(process, args.name_span))
|
||||
.map(|(_, process)| process_dict(process, args.call_info.name_span))
|
||||
.collect::<VecDeque<_>>();
|
||||
|
||||
Ok(list.from_input_stream())
|
||||
|
|
|
@ -3,13 +3,13 @@ use crate::object::base::reject_fields;
|
|||
use crate::prelude::*;
|
||||
|
||||
pub fn reject(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name_span = args.name_span;
|
||||
let name_span = args.call_info.name_span;
|
||||
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Reject requires fields",
|
||||
"needs parameter",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::errors::ShellError;
|
||||
use crate::prelude::*;
|
||||
use crate::parser::registry::{CommandConfig, NamedType, PositionalType};
|
||||
use crate::parser::hir::SyntaxType;
|
||||
use crate::parser::registry::{CommandConfig, NamedType, PositionalType};
|
||||
use crate::prelude::*;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
pub struct Remove;
|
||||
|
@ -31,28 +31,25 @@ impl Command for Remove {
|
|||
}
|
||||
|
||||
pub fn rm(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut full_path = args.env
|
||||
.lock()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
let mut full_path = args.env.lock().unwrap().path().to_path_buf();
|
||||
|
||||
|
||||
match args.nth(0)
|
||||
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
|
||||
.as_string()?
|
||||
.as_str() {
|
||||
"." | ".." => return Err(ShellError::string("\".\" and \"..\" may not be removed")),
|
||||
file => full_path.push(file),
|
||||
match args
|
||||
.nth(0)
|
||||
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
|
||||
.as_string()?
|
||||
.as_str()
|
||||
{
|
||||
"." | ".." => return Err(ShellError::string("\".\" and \"..\" may not be removed")),
|
||||
file => full_path.push(file),
|
||||
}
|
||||
|
||||
|
||||
if full_path.is_dir() {
|
||||
if !args.has("recursive") {
|
||||
return Err(ShellError::labeled_error(
|
||||
"is a directory",
|
||||
"",
|
||||
args.name_span.unwrap()));
|
||||
"is a directory",
|
||||
"",
|
||||
args.call_info.name_span.unwrap(),
|
||||
));
|
||||
}
|
||||
std::fs::remove_dir_all(&full_path).expect("can not remove directory");
|
||||
} else if full_path.is_file() {
|
||||
|
|
|
@ -8,15 +8,15 @@ use crate::parser::Spanned;
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
if args.args.positional.is_none() {
|
||||
if args.call_info.args.positional.is_none() {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Save requires a filepath",
|
||||
"needs path",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
let positional = match args.args.positional {
|
||||
let positional = match args.call_info.args.positional {
|
||||
None => return Err(ShellError::string("save requires a filepath")),
|
||||
Some(p) => p,
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ pub fn skip_while(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
return Err(ShellError::maybe_labeled_error(
|
||||
"Where requires a condition",
|
||||
"needs condition",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ use log::trace;
|
|||
|
||||
pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let positional: Vec<_> = args.positional_iter().cloned().collect();
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
if positional.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Split-column needs more information",
|
||||
"needs parameter (eg split-column \",\")",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,13 @@ use log::trace;
|
|||
|
||||
pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let positional: Vec<Spanned<Value>> = args.positional_iter().cloned().collect();
|
||||
let span = args.name_span;
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
if positional.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Split-row needs more information",
|
||||
"needs parameter (eg split-row \"\\n\")",
|
||||
args.name_span,
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,11 @@ use sys_info::*;
|
|||
use sysinfo::{ComponentExt, DiskExt, NetworkExt, RefreshKind, SystemExt};
|
||||
|
||||
pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut idx = SpannedDictBuilder::new(args.name_span);
|
||||
let name_span = args.call_info.name_span;
|
||||
let mut idx = SpannedDictBuilder::new(name_span);
|
||||
|
||||
if let (Ok(name), Ok(version)) = (os_type(), os_release()) {
|
||||
let mut os_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut os_idx = SpannedDictBuilder::new(name_span);
|
||||
os_idx.insert("name", Primitive::String(name));
|
||||
os_idx.insert("version", Primitive::String(version));
|
||||
|
||||
|
@ -18,7 +19,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
}
|
||||
|
||||
if let (Ok(num_cpu), Ok(cpu_speed)) = (cpu_num(), cpu_speed()) {
|
||||
let mut cpu_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut cpu_idx = SpannedDictBuilder::new(name_span);
|
||||
cpu_idx.insert("num", Primitive::Int(num_cpu as i64));
|
||||
cpu_idx.insert("speed", Primitive::Int(cpu_speed as i64));
|
||||
|
||||
|
@ -26,7 +27,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
}
|
||||
|
||||
if let Ok(x) = loadavg() {
|
||||
let mut load_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut load_idx = SpannedDictBuilder::new(name_span);
|
||||
|
||||
load_idx.insert("1min", Primitive::Float(OF64::from(x.one)));
|
||||
load_idx.insert("5min", Primitive::Float(OF64::from(x.five)));
|
||||
|
@ -36,7 +37,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
}
|
||||
|
||||
if let Ok(x) = mem_info() {
|
||||
let mut mem_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut mem_idx = SpannedDictBuilder::new(name_span);
|
||||
|
||||
mem_idx.insert("total", Primitive::Bytes(x.total as u64 * 1024));
|
||||
mem_idx.insert("free", Primitive::Bytes(x.free as u64 * 1024));
|
||||
|
@ -70,7 +71,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
#[cfg(not(windows))]
|
||||
{
|
||||
if let Ok(x) = boottime() {
|
||||
let mut boottime_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut boottime_idx = SpannedDictBuilder::new(name_span);
|
||||
boottime_idx.insert("days", Primitive::Int(x.tv_sec / (24 * 3600)));
|
||||
boottime_idx.insert("hours", Primitive::Int((x.tv_sec / 3600) % 24));
|
||||
boottime_idx.insert("mins", Primitive::Int((x.tv_sec / 60) % 60));
|
||||
|
@ -84,7 +85,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
if components_list.len() > 0 {
|
||||
let mut v: Vec<Spanned<Value>> = vec![];
|
||||
for component in components_list {
|
||||
let mut component_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut component_idx = SpannedDictBuilder::new(name_span);
|
||||
component_idx.insert("name", Primitive::String(component.get_label().to_string()));
|
||||
component_idx.insert(
|
||||
"temp",
|
||||
|
@ -107,7 +108,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
let mut v = vec![];
|
||||
|
||||
for disk in disks {
|
||||
let mut disk_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut disk_idx = SpannedDictBuilder::new(name_span);
|
||||
disk_idx.insert("name", Value::string(disk.get_name().to_string_lossy()));
|
||||
disk_idx.insert("available", Value::bytes(disk.get_available_space()));
|
||||
disk_idx.insert("total", Value::bytes(disk.get_total_space()));
|
||||
|
@ -121,7 +122,7 @@ pub fn sysinfo(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
let incoming = network.get_income();
|
||||
let outgoing = network.get_outcome();
|
||||
|
||||
let mut network_idx = SpannedDictBuilder::new(args.name_span);
|
||||
let mut network_idx = SpannedDictBuilder::new(name_span);
|
||||
network_idx.insert("incoming", Value::bytes(incoming));
|
||||
network_idx.insert("outgoing", Value::bytes(outgoing));
|
||||
idx.insert_spanned("network", network_idx);
|
||||
|
|
|
@ -42,7 +42,7 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value {
|
|||
|
||||
pub fn to_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let name_span = args.name_span;
|
||||
let name_span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
|||
|
||||
pub fn to_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let name_span = args.name_span;
|
||||
let name_span = args.call_info.name_span;
|
||||
|
||||
Ok(out
|
||||
.values
|
||||
|
|
|
@ -40,7 +40,7 @@ pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
|
|||
|
||||
pub fn to_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let out = args.input;
|
||||
let name_span = args.name_span;
|
||||
let name_span = args.call_info.name_span;
|
||||
Ok(out
|
||||
.values
|
||||
.map(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::commands::command::{Sink, SinkCommandArgs};
|
||||
use crate::commands::command::{CallInfo, Sink, SinkCommandArgs};
|
||||
use crate::parser::{
|
||||
registry::{Args, CommandConfig, CommandRegistry},
|
||||
Span,
|
||||
|
@ -88,9 +88,11 @@ impl Context {
|
|||
) -> Result<(), ShellError> {
|
||||
let command_args = SinkCommandArgs {
|
||||
ctx: self.clone(),
|
||||
name_span,
|
||||
source_map: self.source_map.clone(),
|
||||
args,
|
||||
call_info: CallInfo {
|
||||
name_span,
|
||||
source_map: self.source_map.clone(),
|
||||
args,
|
||||
},
|
||||
input,
|
||||
};
|
||||
|
||||
|
@ -120,9 +122,11 @@ impl Context {
|
|||
let command_args = CommandArgs {
|
||||
host: self.host.clone(),
|
||||
env: self.env.clone(),
|
||||
name_span,
|
||||
source_map,
|
||||
args,
|
||||
call_info: CallInfo {
|
||||
name_span,
|
||||
source_map,
|
||||
args,
|
||||
},
|
||||
input,
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ mod plugin;
|
|||
mod shell;
|
||||
mod stream;
|
||||
|
||||
pub use crate::commands::command::{ReturnSuccess, ReturnValue};
|
||||
pub use crate::commands::command::{CallInfo, ReturnSuccess, ReturnValue};
|
||||
pub use crate::context::SpanSource;
|
||||
pub use crate::env::host::BasicHost;
|
||||
pub use crate::parser::parse::span::SpannedItem;
|
||||
pub use crate::parser::Spanned;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::{Args, CommandConfig, ReturnValue, ShellError, Spanned, Value};
|
||||
use crate::{CallInfo, CommandConfig, ReturnValue, ShellError, Spanned, Value};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
|
||||
pub trait Plugin {
|
||||
fn config(&mut self) -> Result<CommandConfig, ShellError>;
|
||||
#[allow(unused)]
|
||||
fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> {
|
||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> {
|
||||
Err(ShellError::string(
|
||||
"`begin_filter` not implemented in plugin",
|
||||
))
|
||||
|
@ -15,7 +15,7 @@ pub trait Plugin {
|
|||
Err(ShellError::string("`filter` not implemented in plugin"))
|
||||
}
|
||||
#[allow(unused)]
|
||||
fn sink(&mut self, args: Args, input: Vec<Spanned<Value>>) {}
|
||||
fn sink(&mut self, call_info: CallInfo, input: Vec<Spanned<Value>>) {}
|
||||
|
||||
fn quit(&mut self) {
|
||||
return;
|
||||
|
@ -134,8 +134,14 @@ fn send_response<T: Serialize>(result: T) {
|
|||
#[allow(non_camel_case_types)]
|
||||
pub enum NuCommand {
|
||||
config,
|
||||
begin_filter { params: Args },
|
||||
filter { params: Spanned<Value> },
|
||||
sink { params: (Args, Vec<Spanned<Value>>) },
|
||||
begin_filter {
|
||||
params: CallInfo,
|
||||
},
|
||||
filter {
|
||||
params: Spanned<Value>,
|
||||
},
|
||||
sink {
|
||||
params: (CallInfo, Vec<Spanned<Value>>),
|
||||
},
|
||||
quit,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#![feature(option_flattening)]
|
||||
use crossterm::{cursor, terminal, Attribute, RawScreen};
|
||||
use indexmap::IndexMap;
|
||||
use nu::{serve_plugin, Args, CommandConfig, NamedType, Plugin, ShellError, Spanned, Value};
|
||||
use nu::{
|
||||
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, ShellError, SpanSource, Spanned,
|
||||
Value,
|
||||
};
|
||||
use pretty_hex::*;
|
||||
|
||||
struct BinaryView;
|
||||
|
@ -25,14 +29,15 @@ impl Plugin for BinaryView {
|
|||
})
|
||||
}
|
||||
|
||||
fn sink(&mut self, args: Args, input: Vec<Spanned<Value>>) {
|
||||
fn sink(&mut self, call_info: CallInfo, input: Vec<Spanned<Value>>) {
|
||||
for v in input {
|
||||
match v {
|
||||
Spanned {
|
||||
item: Value::Binary(b),
|
||||
..
|
||||
span,
|
||||
} => {
|
||||
let _ = view_binary(&b, args.has("lores"));
|
||||
let source = span.source.map(|x| call_info.source_map.get(&x)).flatten();
|
||||
let _ = view_binary(&b, source, call_info.args.has("lores"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -40,17 +45,21 @@ impl Plugin for BinaryView {
|
|||
}
|
||||
}
|
||||
|
||||
fn view_binary(b: &[u8], lores_mode: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn view_binary(
|
||||
b: &[u8],
|
||||
source: Option<&SpanSource>,
|
||||
lores_mode: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
if b.len() > 3 {
|
||||
match (b[0], b[1], b[2]) {
|
||||
(0x4e, 0x45, 0x53) => {
|
||||
view_contents_interactive(b, lores_mode)?;
|
||||
view_contents_interactive(b, source, lores_mode)?;
|
||||
return Ok(());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
view_contents(b, lores_mode)?;
|
||||
view_contents(b, source, lores_mode)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -247,7 +256,11 @@ fn load_from_jpg_buffer(buffer: &[u8]) -> Option<(RawImageBuffer)> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn view_contents(buffer: &[u8], lores_mode: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
pub fn view_contents(
|
||||
buffer: &[u8],
|
||||
_source: Option<&SpanSource>,
|
||||
lores_mode: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut raw_image_buffer = load_from_png_buffer(buffer);
|
||||
|
||||
if raw_image_buffer.is_none() {
|
||||
|
@ -332,14 +345,29 @@ pub fn view_contents(buffer: &[u8], lores_mode: bool) -> Result<(), Box<dyn std:
|
|||
|
||||
pub fn view_contents_interactive(
|
||||
buffer: &[u8],
|
||||
source: Option<&SpanSource>,
|
||||
lores_mode: bool,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use rawkey::{KeyCode, RawKey};
|
||||
|
||||
let sav_path = if let Some(SpanSource::File(f)) = source {
|
||||
let mut path = std::path::PathBuf::from(f);
|
||||
path.set_extension("sav");
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut nes = neso::Nes::new(48000.0);
|
||||
let rawkey = RawKey::new();
|
||||
nes.load_rom(&buffer);
|
||||
|
||||
if let Some(ref sav_path) = sav_path {
|
||||
if let Ok(contents) = std::fs::read(sav_path) {
|
||||
let _ = nes.load_state(&contents);
|
||||
}
|
||||
}
|
||||
|
||||
nes.reset();
|
||||
|
||||
if let Ok(_raw) = RawScreen::into_raw_mode() {
|
||||
|
@ -403,6 +431,13 @@ pub fn view_contents_interactive(
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(ref sav_path) = sav_path {
|
||||
let buffer = nes.save_state();
|
||||
if let Ok(buffer) = buffer {
|
||||
let _ = std::fs::write(sav_path, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
let cursor = cursor();
|
||||
let _ = cursor.show();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, Args, CommandConfig, NamedType, Plugin, PositionalType, Primitive, ReturnSuccess,
|
||||
ReturnValue, ShellError, Spanned, SpannedItem, Value,
|
||||
serve_plugin, CallInfo, CommandConfig, NamedType, Plugin, PositionalType, Primitive,
|
||||
ReturnSuccess, ReturnValue, ShellError, Spanned, SpannedItem, Value,
|
||||
};
|
||||
|
||||
struct Inc {
|
||||
|
@ -99,18 +99,18 @@ impl Plugin for Inc {
|
|||
rest_positional: true,
|
||||
})
|
||||
}
|
||||
fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> {
|
||||
if args.has("major") {
|
||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> {
|
||||
if call_info.args.has("major") {
|
||||
self.major = true;
|
||||
}
|
||||
if args.has("minor") {
|
||||
if call_info.args.has("minor") {
|
||||
self.minor = true;
|
||||
}
|
||||
if args.has("patch") {
|
||||
if call_info.args.has("patch") {
|
||||
self.patch = true;
|
||||
}
|
||||
|
||||
if let Some(args) = args.positional {
|
||||
if let Some(args) = call_info.args.positional {
|
||||
for arg in args {
|
||||
match arg {
|
||||
Spanned {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use indexmap::IndexMap;
|
||||
use nu::{
|
||||
serve_plugin, Args, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError,
|
||||
Spanned, Value,
|
||||
serve_plugin, CallInfo, CommandConfig, Plugin, Primitive, ReturnSuccess, ReturnValue,
|
||||
ShellError, Spanned, Value,
|
||||
};
|
||||
|
||||
struct NewSkip {
|
||||
|
@ -24,8 +24,8 @@ impl Plugin for NewSkip {
|
|||
rest_positional: true,
|
||||
})
|
||||
}
|
||||
fn begin_filter(&mut self, args: Args) -> Result<(), ShellError> {
|
||||
if let Some(args) = args.positional {
|
||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<(), ShellError> {
|
||||
if let Some(args) = call_info.args.positional {
|
||||
for arg in args {
|
||||
match arg {
|
||||
Spanned {
|
||||
|
@ -34,7 +34,13 @@ impl Plugin for NewSkip {
|
|||
} => {
|
||||
self.skip_amount = i;
|
||||
}
|
||||
_ => return Err(ShellError::labeled_error("Unrecognized type in params", "expected an integer", arg.span)),
|
||||
_ => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Unrecognized type in params",
|
||||
"expected an integer",
|
||||
arg.span,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use derive_new::new;
|
||||
use indexmap::IndexMap;
|
||||
use nu::{serve_plugin, Args, CommandConfig, Plugin, ShellError, Spanned, Value};
|
||||
use nu::{serve_plugin, CallInfo, CommandConfig, Plugin, ShellError, Spanned, Value};
|
||||
use ptree::item::StringItem;
|
||||
use ptree::output::print_tree_with;
|
||||
use ptree::print_config::PrintConfig;
|
||||
|
@ -91,7 +91,7 @@ impl Plugin for TreeViewer {
|
|||
})
|
||||
}
|
||||
|
||||
fn sink(&mut self, _args: Args, input: Vec<Spanned<Value>>) {
|
||||
fn sink(&mut self, _call_info: CallInfo, input: Vec<Spanned<Value>>) {
|
||||
if input.len() > 0 {
|
||||
for i in input.iter() {
|
||||
let view = TreeView::from_value(&i);
|
||||
|
|
Loading…
Reference in a new issue