Merge pull request #287 from jonathandturner/more_per_item

Add more support for per-item
This commit is contained in:
Jonathan Turner 2019-08-15 18:53:20 +12:00 committed by GitHub
commit 7bb62af46f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 266 additions and 205 deletions

View File

@ -5,7 +5,7 @@ use crate::commands::classified::{
};
use crate::commands::plugin::JsonRpc;
use crate::commands::plugin::{PluginCommand, PluginSink};
use crate::commands::static_command;
use crate::commands::whole_stream_command;
use crate::context::Context;
crate use crate::errors::ShellError;
use crate::git::current_branch;
@ -67,14 +67,14 @@ fn load_plugin(path: &std::path::Path, context: &mut Context) -> Result<(), Shel
if params.is_filter {
let fname = fname.to_string();
let name = params.name.clone();
context.add_commands(vec![static_command(PluginCommand::new(
context.add_commands(vec![whole_stream_command(PluginCommand::new(
name, fname, params,
))]);
Ok(())
} else {
let fname = fname.to_string();
let name = params.name.clone();
context.add_commands(vec![static_command(PluginSink::new(
context.add_commands(vec![whole_stream_command(PluginSink::new(
name, fname, params,
))]);
Ok(())
@ -178,25 +178,24 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
command("to-yaml", Box::new(to_yaml::to_yaml)),
command("sort-by", Box::new(sort_by::sort_by)),
command("tags", Box::new(tags::tags)),
static_command(Get),
//static_command(Cd),
static_command(Remove),
static_command(Open),
whole_stream_command(Get),
per_item_command(Remove),
per_item_command(Open),
per_item_command(Where),
static_command(Config),
static_command(SkipWhile),
whole_stream_command(Config),
whole_stream_command(SkipWhile),
per_item_command(Enter),
static_command(Exit),
static_command(Clip),
static_command(Autoview),
static_command(Cpy),
static_command(Date),
static_command(Mkdir),
static_command(Move),
static_command(Save),
static_command(Table),
static_command(VTable),
static_command(Which),
whole_stream_command(Exit),
whole_stream_command(Clip),
whole_stream_command(Autoview),
per_item_command(Cpy),
whole_stream_command(Date),
per_item_command(Mkdir),
per_item_command(Move),
whole_stream_command(Save),
whole_stream_command(Table),
whole_stream_command(VTable),
whole_stream_command(Which),
]);
}
let _ = load_plugins(&mut context);
@ -356,7 +355,7 @@ async fn process_line(readline: Result<String, ReadlineError>, ctx: &mut Context
_ => pipeline
.commands
.push(ClassifiedCommand::Internal(InternalCommand {
command: static_command(autoview::Autoview),
command: whole_stream_command(autoview::Autoview),
name_span: Span::unknown(),
args: hir::Call::new(
Box::new(hir::Expression::synthetic_string("autoview")),

View File

@ -58,8 +58,8 @@ crate use autoview::Autoview;
//crate use cd::Cd;
crate use clip::Clip;
crate use command::{
command, per_item_command, static_command, Command, CommandArgs, PerItemCommand,
RawCommandArgs, StaticCommand, UnevaluatedCallInfo,
command, per_item_command, whole_stream_command, Command, CommandArgs, PerItemCommand,
RawCommandArgs, UnevaluatedCallInfo, WholeStreamCommand,
};
crate use config::Config;
crate use cp::Cpy;

View File

@ -1,4 +1,4 @@
use crate::commands::{RawCommandArgs, StaticCommand};
use crate::commands::{RawCommandArgs, WholeStreamCommand};
use crate::errors::ShellError;
use crate::prelude::*;
@ -7,7 +7,7 @@ pub struct Autoview;
#[derive(Deserialize)]
pub struct AutoviewArgs {}
impl StaticCommand for Autoview {
impl WholeStreamCommand for Autoview {
fn name(&self) -> &str {
"autoview"
}

View File

@ -1,4 +1,4 @@
use crate::commands::{CommandArgs, StaticCommand};
use crate::commands::{CommandArgs, WholeStreamCommand};
use crate::context::CommandRegistry;
use crate::errors::{labelled, ShellError};
use crate::prelude::*;
@ -11,7 +11,7 @@ pub struct Clip;
#[derive(Deserialize)]
pub struct ClipArgs {}
impl StaticCommand for Clip {
impl WholeStreamCommand for Clip {
fn name(&self) -> &str {
"clip"
}

View File

@ -41,6 +41,33 @@ impl UnevaluatedCallInfo {
name_span: self.name_span,
})
}
pub fn has_it_or_block(&self) -> bool {
use hir::RawExpression;
use hir::Variable;
if let Some(positional) = &self.args.positional() {
for pos in positional {
match pos {
Tagged {
item: RawExpression::Variable(Variable::It(_)),
..
} => {
return true;
}
Tagged {
item: RawExpression::Block(_),
..
} => {
return true;
}
_ => {}
}
}
}
false
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
@ -91,13 +118,13 @@ impl CommandArgs {
pub fn evaluate_once(
self,
registry: &registry::CommandRegistry,
) -> Result<EvaluatedStaticCommandArgs, ShellError> {
) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
let host = self.host.clone();
let shell_manager = self.shell_manager.clone();
let input = self.input;
let call_info = self.call_info.evaluate(registry, &Scope::empty())?;
Ok(EvaluatedStaticCommandArgs::new(
Ok(EvaluatedWholeStreamCommandArgs::new(
host,
shell_manager,
call_info,
@ -217,26 +244,26 @@ impl<T> RunnableRawArgs<T> {
}
}
pub struct EvaluatedStaticCommandArgs {
pub struct EvaluatedWholeStreamCommandArgs {
pub args: EvaluatedCommandArgs,
pub input: InputStream,
}
impl Deref for EvaluatedStaticCommandArgs {
impl Deref for EvaluatedWholeStreamCommandArgs {
type Target = EvaluatedCommandArgs;
fn deref(&self) -> &Self::Target {
&self.args
}
}
impl EvaluatedStaticCommandArgs {
impl EvaluatedWholeStreamCommandArgs {
pub fn new(
host: Arc<Mutex<dyn Host>>,
shell_manager: ShellManager,
call_info: CallInfo,
input: impl Into<InputStream>,
) -> EvaluatedStaticCommandArgs {
EvaluatedStaticCommandArgs {
) -> EvaluatedWholeStreamCommandArgs {
EvaluatedWholeStreamCommandArgs {
args: EvaluatedCommandArgs {
host,
shell_manager,
@ -251,13 +278,13 @@ impl EvaluatedStaticCommandArgs {
}
pub fn parts(self) -> (InputStream, registry::EvaluatedArgs) {
let EvaluatedStaticCommandArgs { args, input } = self;
let EvaluatedWholeStreamCommandArgs { args, input } = self;
(input, args.call_info.args)
}
pub fn split(self) -> (InputStream, EvaluatedCommandArgs) {
let EvaluatedStaticCommandArgs { args, input } = self;
let EvaluatedWholeStreamCommandArgs { args, input } = self;
(input, args)
}
@ -386,7 +413,7 @@ impl ReturnSuccess {
}
}
pub trait StaticCommand: Send + Sync {
pub trait WholeStreamCommand: Send + Sync {
fn name(&self) -> &str;
fn run(
@ -411,8 +438,9 @@ pub trait PerItemCommand: Send + Sync {
fn run(
&self,
args: RawCommandArgs,
registry: &registry::CommandRegistry,
call_info: &CallInfo,
registry: &CommandRegistry,
shell_manager: &ShellManager,
input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError>;
@ -428,21 +456,21 @@ pub trait PerItemCommand: Send + Sync {
}
pub enum Command {
Static(Arc<dyn StaticCommand>),
WholeStream(Arc<dyn WholeStreamCommand>),
PerItem(Arc<dyn PerItemCommand>),
}
impl Command {
pub fn name(&self) -> &str {
match self {
Command::Static(command) => command.name(),
Command::WholeStream(command) => command.name(),
Command::PerItem(command) => command.name(),
}
}
pub fn signature(&self) -> Signature {
match self {
Command::Static(command) => command.signature(),
Command::WholeStream(command) => command.signature(),
Command::PerItem(command) => command.signature(),
}
}
@ -453,7 +481,7 @@ impl Command {
registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> {
match self {
Command::Static(command) => command.run(args, registry),
Command::WholeStream(command) => command.run(args, registry),
Command::PerItem(command) => self.run_helper(command.clone(), args, registry.clone()),
}
}
@ -469,13 +497,39 @@ impl Command {
shell_manager: args.shell_manager,
call_info: args.call_info,
};
let out = args
.input
.values
.map(move |x| command.run(raw_args.clone(), &registry, x).unwrap())
.flatten();
Ok(out.to_output_stream())
if raw_args.call_info.has_it_or_block() {
let out = args
.input
.values
.map(move |x| {
let call_info = raw_args
.clone()
.call_info
.evaluate(&registry, &Scope::it_value(x.clone()))
.unwrap();
match command.run(&call_info, &registry, &raw_args.shell_manager, x) {
Ok(o) => o,
Err(e) => VecDeque::from(vec![ReturnValue::Err(e)]),
}
})
.flatten();
Ok(out.to_output_stream())
} else {
let nothing = Value::nothing().tagged(Tag::unknown());
let call_info = raw_args
.clone()
.call_info
.evaluate(&registry, &Scope::it_value(nothing.clone()))
.unwrap();
// We don't have an $it or block, so just execute what we have
let out = match command.run(&call_info, &registry, &raw_args.shell_manager, nothing) {
Ok(o) => o,
Err(e) => VecDeque::from(vec![ReturnValue::Err(e)]),
};
Ok(out.to_output_stream())
}
}
}
@ -485,7 +539,7 @@ pub struct FnFilterCommand {
func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
}
impl StaticCommand for FnFilterCommand {
impl WholeStreamCommand for FnFilterCommand {
fn name(&self) -> &str {
&self.name
}
@ -542,7 +596,7 @@ pub struct FnRawCommand {
>,
}
impl StaticCommand for FnRawCommand {
impl WholeStreamCommand for FnRawCommand {
fn name(&self) -> &str {
&self.name
}
@ -564,14 +618,14 @@ pub fn command(
+ Sync,
>,
) -> Arc<Command> {
Arc::new(Command::Static(Arc::new(FnRawCommand {
Arc::new(Command::WholeStream(Arc::new(FnRawCommand {
name: name.to_string(),
func,
})))
}
pub fn static_command(command: impl StaticCommand + 'static) -> Arc<Command> {
Arc::new(Command::Static(Arc::new(command)))
pub fn whole_stream_command(command: impl WholeStreamCommand + 'static) -> Arc<Command> {
Arc::new(Command::WholeStream(Arc::new(command)))
}
pub fn per_item_command(command: impl PerItemCommand + 'static) -> Arc<Command> {
@ -583,7 +637,7 @@ pub fn filter(
name: &str,
func: fn(EvaluatedFilterCommandArgs) -> Result<OutputStream, ShellError>,
) -> Arc<Command> {
Arc::new(Command::Static(Arc::new(FnFilterCommand {
Arc::new(Command::WholeStream(Arc::new(FnFilterCommand {
name: name.to_string(),
func,
})))

View File

@ -1,6 +1,6 @@
use crate::prelude::*;
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::object::{config, Value};
use crate::parser::hir::SyntaxType;
@ -18,7 +18,7 @@ pub struct ConfigArgs {
path: Tagged<bool>,
}
impl StaticCommand for Config {
impl WholeStreamCommand for Config {
fn name(&self) -> &str {
"config"
}

View File

@ -7,13 +7,15 @@ use std::path::PathBuf;
pub struct Cpy;
impl StaticCommand for Cpy {
impl PerItemCommand for Cpy {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
cp(args, registry)
call_info: &CallInfo,
_registry: &CommandRegistry,
shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
cp(call_info, shell_manager)
}
fn name(&self) -> &str {
@ -27,13 +29,16 @@ impl StaticCommand for Cpy {
}
}
pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let mut source = PathBuf::from(args.shell_manager.path());
let mut destination = PathBuf::from(args.shell_manager.path());
let name_span = args.call_info.name_span;
let args = args.evaluate_once(registry)?;
pub fn cp(
call_info: &CallInfo,
shell_manager: &ShellManager,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let mut source = PathBuf::from(shell_manager.path());
let mut destination = PathBuf::from(shell_manager.path());
let name_span = call_info.name_span;
match args
match call_info
.args
.nth(0)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
.as_string()?
@ -44,7 +49,8 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
}
}
match args
match call_info
.args
.nth(1)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
.as_string()?
@ -61,7 +67,7 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
return Err(ShellError::labeled_error(
"Invalid pattern.",
"Invalid pattern.",
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
@ -69,11 +75,11 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
if sources.len() == 1 {
if let Ok(entry) = &sources[0] {
if entry.is_dir() && !args.has("recursive") {
if entry.is_dir() && !call_info.args.has("recursive") {
return Err(ShellError::labeled_error(
"is a directory (not copied). Try using \"--recursive\".",
"is a directory (not copied). Try using \"--recursive\".",
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
@ -242,7 +248,7 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
return Err(ShellError::labeled_error(
"Copy aborted (directories found). Recursive copying in patterns not supported yet (try copying the directory directly)",
"Copy aborted (directories found). Recursive copying in patterns not supported yet (try copying the directory directly)",
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
@ -257,7 +263,7 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
return Err(ShellError::labeled_error(
e.to_string(),
e.to_string(),
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
Ok(o) => o,
@ -275,10 +281,10 @@ pub fn cp(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
"Copy aborted. (Does {:?} exist?)",
&destination.file_name().unwrap()
),
args.nth(1).unwrap().span(),
call_info.args.nth(1).unwrap().span(),
));
}
}
Ok(OutputStream::empty())
Ok(VecDeque::new())
}

View File

@ -3,7 +3,7 @@ use crate::object::{Dictionary, Value};
use crate::prelude::*;
use chrono::{DateTime, Local, Utc};
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::parser::registry::Signature;
use chrono::{Datelike, TimeZone, Timelike};
use core::fmt::Display;
@ -11,7 +11,7 @@ use indexmap::IndexMap;
pub struct Date;
impl StaticCommand for Date {
impl WholeStreamCommand for Date {
fn run(
&self,
args: CommandArgs,

View File

@ -1,7 +1,6 @@
use crate::commands::command::CommandAction;
use crate::commands::{PerItemCommand, RawCommandArgs};
use crate::commands::PerItemCommand;
use crate::errors::ShellError;
use crate::evaluate::Scope;
use crate::parser::registry;
use crate::prelude::*;
@ -18,15 +17,11 @@ impl PerItemCommand for Enter {
fn run(
&self,
args: RawCommandArgs,
registry: &registry::CommandRegistry,
input: Tagged<Value>,
call_info: &CallInfo,
_registry: &registry::CommandRegistry,
_shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let call_info = args
.call_info
.evaluate(registry, &Scope::it_value(input))
.unwrap();
match call_info.args.expect_nth(0)? {
Tagged {
item: Value::Primitive(Primitive::String(location)),

View File

@ -1,11 +1,11 @@
use crate::commands::command::{CommandAction, StaticCommand};
use crate::commands::command::{CommandAction, WholeStreamCommand};
use crate::errors::ShellError;
use crate::parser::registry::{CommandRegistry, Signature};
use crate::prelude::*;
pub struct Exit;
impl StaticCommand for Exit {
impl WholeStreamCommand for Exit {
fn run(
&self,
args: CommandArgs,

View File

@ -1,4 +1,4 @@
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::object::Value;
use crate::prelude::*;
@ -10,7 +10,7 @@ pub struct GetArgs {
rest: Vec<Tagged<String>>,
}
impl StaticCommand for Get {
impl WholeStreamCommand for Get {
fn name(&self) -> &str {
"get"
}

View File

@ -6,13 +6,15 @@ use std::path::{Path, PathBuf};
pub struct Mkdir;
impl StaticCommand for Mkdir {
impl PerItemCommand for Mkdir {
fn run(
&self,
args: CommandArgs,
call_info: &CallInfo,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
mkdir(args, registry)
shell_manager: &ShellManager,
input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
mkdir(call_info, registry, shell_manager, input)
}
fn name(&self) -> &str {
@ -24,12 +26,15 @@ impl StaticCommand for Mkdir {
}
}
pub fn mkdir(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let args = args.evaluate_once(registry)?;
pub fn mkdir(
call_info: &CallInfo,
_registry: &CommandRegistry,
shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let mut full_path = PathBuf::from(shell_manager.path());
let mut full_path = PathBuf::from(args.shell_manager.path());
match &args.nth(0) {
match &call_info.args.nth(0) {
Some(Tagged { item: value, .. }) => full_path.push(Path::new(&value.as_string()?)),
_ => {}
}
@ -38,8 +43,8 @@ pub fn mkdir(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStre
Err(reason) => Err(ShellError::labeled_error(
reason.to_string(),
reason.to_string(),
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
)),
Ok(_) => Ok(OutputStream::empty()),
Ok(_) => Ok(VecDeque::new()),
}
}

View File

@ -9,13 +9,15 @@ use crate::utils::FileStructure;
pub struct Move;
impl StaticCommand for Move {
impl PerItemCommand for Move {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
mv(args, registry)
call_info: &CallInfo,
_registry: &CommandRegistry,
shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
mv(call_info, shell_manager)
}
fn name(&self) -> &str {
@ -27,13 +29,16 @@ impl StaticCommand for Move {
}
}
pub fn mv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
let mut source = PathBuf::from(args.shell_manager.path());
let mut destination = PathBuf::from(args.shell_manager.path());
let span = args.name_span();
let args = args.evaluate_once(registry)?;
pub fn mv(
call_info: &CallInfo,
shell_manager: &ShellManager,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let mut source = PathBuf::from(shell_manager.path());
let mut destination = PathBuf::from(shell_manager.path());
let span = call_info.name_span;
match args
match call_info
.args
.nth(0)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
.as_string()?
@ -44,7 +49,8 @@ pub fn mv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
}
}
match args
match call_info
.args
.nth(1)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
.as_string()?
@ -61,7 +67,7 @@ pub fn mv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
return Err(ShellError::labeled_error(
"Invalid pattern.",
"Invalid pattern.",
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
@ -227,7 +233,7 @@ pub fn mv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
return Err(ShellError::labeled_error(
"Rename aborted (directories found). Renaming in patterns not supported yet (try moving the directory directly)",
"Rename aborted (directories found). Renaming in patterns not supported yet (try moving the directory directly)",
args.nth(0).unwrap().span(),
call_info.args.nth(0).unwrap().span(),
));
}
@ -270,10 +276,10 @@ pub fn mv(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
"Rename aborted. (Does {:?} exist?)",
&destination.file_name().unwrap()
),
args.nth(1).unwrap().span(),
call_info.args.nth(1).unwrap().span(),
));
}
}
Ok(OutputStream::empty())
Ok(VecDeque::new())
}

View File

@ -1,9 +1,8 @@
use crate::commands::StaticCommand;
use crate::context::SpanSource;
use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::hir::SyntaxType;
use crate::parser::registry::{self, Signature};
use crate::parser::registry::Signature;
use crate::prelude::*;
use mime::Mime;
use std::path::{Path, PathBuf};
@ -11,13 +10,7 @@ use std::str::FromStr;
use uuid::Uuid;
pub struct Open;
#[derive(Deserialize)]
pub struct OpenArgs {
path: Tagged<PathBuf>,
raw: bool,
}
impl StaticCommand for Open {
impl PerItemCommand for Open {
fn name(&self) -> &str {
"open"
}
@ -30,33 +23,40 @@ impl StaticCommand for Open {
fn run(
&self,
args: CommandArgs,
registry: &registry::CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, run)?.run()
call_info: &CallInfo,
_registry: &CommandRegistry,
shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
run(call_info, shell_manager)
}
}
fn run(
OpenArgs { raw, path }: OpenArgs,
RunnableContext {
shell_manager,
name,
..
}: RunnableContext,
) -> Result<OutputStream, ShellError> {
call_info: &CallInfo,
shell_manager: &ShellManager,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let cwd = PathBuf::from(shell_manager.path());
let full_path = PathBuf::from(cwd);
let path_str = path.to_str().ok_or(ShellError::type_error(
"Path",
"invalid path".tagged(path.tag()),
))?;
let path = match call_info
.args
.nth(0)
.ok_or_else(|| ShellError::string(&format!("No file or directory specified")))?
{
file => file,
};
let path_str = path.as_string()?;
let (file_extension, contents, contents_tag, span_source) =
fetch(&full_path, path_str, path.span())?;
fetch(&full_path, &path_str, path.span())?;
let file_extension = if raw { None } else { file_extension };
let file_extension = if call_info.args.has("raw") {
None
} else {
file_extension
};
let mut stream = VecDeque::new();
@ -70,7 +70,7 @@ fn run(
match contents {
Value::Primitive(Primitive::String(string)) => {
let value = parse_as_value(file_extension, string, contents_tag, name)?;
let value = parse_as_value(file_extension, string, contents_tag, call_info.name_span)?;
match value {
Tagged {
@ -88,7 +88,7 @@ fn run(
other => stream.push_back(ReturnSuccess::value(other.tagged(contents_tag))),
};
Ok(stream.boxed().to_output_stream())
Ok(stream)
}
pub fn fetch(

View File

@ -1,4 +1,4 @@
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::parser::registry;
use crate::prelude::*;
@ -41,7 +41,7 @@ pub struct PluginCommand {
config: registry::Signature,
}
impl StaticCommand for PluginCommand {
impl WholeStreamCommand for PluginCommand {
fn name(&self) -> &str {
&self.name
}
@ -239,7 +239,7 @@ pub struct PluginSink {
config: registry::Signature,
}
impl StaticCommand for PluginSink {
impl WholeStreamCommand for PluginSink {
fn name(&self) -> &str {
&self.name
}

View File

@ -1,4 +1,3 @@
use crate::commands::StaticCommand;
use crate::errors::ShellError;
use crate::parser::hir::SyntaxType;
use crate::prelude::*;
@ -8,13 +7,7 @@ use std::path::PathBuf;
pub struct Remove;
#[derive(Deserialize)]
pub struct RemoveArgs {
path: Tagged<PathBuf>,
recursive: bool,
}
impl StaticCommand for Remove {
impl PerItemCommand for Remove {
fn name(&self) -> &str {
"rm"
}
@ -27,20 +20,28 @@ impl StaticCommand for Remove {
fn run(
&self,
args: CommandArgs,
registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> {
args.process(registry, rm)?.run()
call_info: &CallInfo,
_registry: &CommandRegistry,
shell_manager: &ShellManager,
_input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
rm(call_info, shell_manager)
}
}
pub fn rm(
RemoveArgs { path, recursive }: RemoveArgs,
context: RunnableContext,
) -> Result<OutputStream, ShellError> {
let mut full_path = context.cwd();
call_info: &CallInfo,
shell_manager: &ShellManager,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let mut full_path = PathBuf::from(shell_manager.path());
match path.item.to_str().unwrap() {
match call_info
.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),
}
@ -57,11 +58,11 @@ pub fn rm(
match entry {
Ok(path) => {
if path.is_dir() {
if !recursive {
if !call_info.args.has("recursive") {
return Err(ShellError::labeled_error(
"is a directory",
"is a directory",
context.name,
call_info.name_span,
));
}
std::fs::remove_dir_all(&path).expect("can not remove directory");
@ -73,5 +74,5 @@ pub fn rm(
}
}
Ok(OutputStream::empty())
Ok(VecDeque::new())
}

View File

@ -2,7 +2,7 @@ use crate::commands::to_csv::{to_string as to_csv_to_string, value_to_csv_value}
use crate::commands::to_json::value_to_json_value;
use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value;
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::object::Value;
use crate::prelude::*;
@ -16,7 +16,7 @@ pub struct SaveArgs {
raw: bool,
}
impl StaticCommand for Save {
impl WholeStreamCommand for Save {
fn name(&self) -> &str {
"save"
}

View File

@ -1,4 +1,4 @@
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::prelude::*;
@ -9,7 +9,7 @@ pub struct SkipWhileArgs {
condition: value::Block,
}
impl StaticCommand for SkipWhile {
impl WholeStreamCommand for SkipWhile {
fn name(&self) -> &str {
"skip-while"
}

View File

@ -1,4 +1,4 @@
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::format::TableView;
use crate::prelude::*;
@ -11,7 +11,7 @@ pub struct TableArgs {
full: bool,
}
impl StaticCommand for Table {
impl WholeStreamCommand for Table {
fn name(&self) -> &str {
"table"
}

View File

@ -1,4 +1,4 @@
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::errors::ShellError;
use crate::format::VTableView;
use crate::prelude::*;
@ -8,7 +8,7 @@ pub struct VTable;
#[derive(Deserialize)]
pub struct VTableArgs {}
impl StaticCommand for VTable {
impl WholeStreamCommand for VTable {
fn name(&self) -> &str {
"vtable"
}

View File

@ -1,4 +1,4 @@
use crate::commands::{PerItemCommand, RawCommandArgs};
use crate::commands::PerItemCommand;
use crate::errors::ShellError;
use crate::parser::hir::SyntaxType;
use crate::parser::registry;
@ -17,16 +17,13 @@ impl PerItemCommand for Where {
fn run(
&self,
args: RawCommandArgs,
registry: &registry::CommandRegistry,
call_info: &CallInfo,
_registry: &registry::CommandRegistry,
_shell_manager: &ShellManager,
input: Tagged<Value>,
) -> Result<VecDeque<ReturnValue>, ShellError> {
let input_clone = input.clone();
let call_info = args
.with_input(vec![input])
.evaluate_once(registry)
.unwrap();
let condition = &call_info.args.call_info.args.positional.unwrap()[0];
let condition = call_info.args.expect_nth(0)?;
match condition {
Tagged {
item: Value::Block(block),

View File

@ -2,12 +2,12 @@ use crate::errors::ShellError;
use crate::object::Value;
use crate::prelude::*;
use crate::commands::StaticCommand;
use crate::commands::WholeStreamCommand;
use crate::parser::registry::Signature;
pub struct Which;
impl StaticCommand for Which {
impl WholeStreamCommand for Which {
fn run(
&self,
args: CommandArgs,

View File

@ -295,7 +295,7 @@ crate fn evaluate_args(
.as_ref()
.map(|p| {
p.iter()
.map(|e| evaluate_baseline_expr(e, &CommandRegistry::empty(), scope, source))
.map(|e| evaluate_baseline_expr(e, registry, scope, source))
.collect()
})
.transpose();

View File

@ -17,8 +17,6 @@ impl Sys {
}
}
//TODO: add more error checking
async fn cpu(tag: Tag) -> Option<Tagged<Value>> {
if let (Ok(num_cpu), Ok(cpu_speed)) = (
heim::cpu::logical_count().await,

View File

@ -34,9 +34,9 @@ macro_rules! trace_stream {
crate use crate::cli::MaybeOwned;
crate use crate::commands::command::{
CommandAction, CommandArgs, ReturnSuccess, ReturnValue, RunnableContext,
CallInfo, CommandAction, CommandArgs, ReturnSuccess, ReturnValue, RunnableContext,
};
crate use crate::commands::StaticCommand;
crate use crate::commands::PerItemCommand;
crate use crate::context::CommandRegistry;
crate use crate::context::{Context, SpanSource};
crate use crate::env::host::handle_unexpected;

View File

@ -1,4 +1,4 @@
use crate::commands::command::EvaluatedStaticCommandArgs;
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
use crate::context::SourceMap;
use crate::object::dir_entry_dict;
use crate::prelude::*;
@ -60,7 +60,7 @@ impl Shell for FilesystemShell {
"filesystem".to_string()
}
fn ls(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let cwd = self.path.clone();
let mut full_path = PathBuf::from(&self.path);
match &args.nth(0) {
@ -133,7 +133,7 @@ impl Shell for FilesystemShell {
Ok(shell_entries.to_output_stream())
}
fn cd(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let path = match args.nth(0) {
None => match dirs::home_dir() {
Some(o) => o,

View File

@ -1,12 +1,12 @@
use crate::commands::command::EvaluatedStaticCommandArgs;
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
use crate::context::SourceMap;
use crate::errors::ShellError;
use crate::stream::OutputStream;
pub trait Shell {
fn name(&self, source_map: &SourceMap) -> String;
fn ls(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError>;
fn cd(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError>;
fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError>;
fn path(&self) -> String;
fn set_path(&mut self, path: String);

View File

@ -1,4 +1,4 @@
use crate::commands::command::EvaluatedStaticCommandArgs;
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
use crate::errors::ShellError;
use crate::prelude::*;
use crate::shell::filesystem_shell::FilesystemShell;
@ -88,12 +88,12 @@ impl ShellManager {
self.set_path(self.path());
}
pub fn ls(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
pub fn ls(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let env = self.shells.lock().unwrap();
env.last().unwrap().ls(args)
}
pub fn cd(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
pub fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let env = self.shells.lock().unwrap();
env.last().unwrap().cd(args)

View File

@ -1,4 +1,4 @@
use crate::commands::command::EvaluatedStaticCommandArgs;
use crate::commands::command::EvaluatedWholeStreamCommandArgs;
use crate::context::SourceMap;
use crate::prelude::*;
use crate::shell::shell::Shell;
@ -65,14 +65,14 @@ impl Shell for ValueShell {
)
}
fn ls(&self, _args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
fn ls(&self, _args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
Ok(self
.members()
.map(|x| ReturnSuccess::value(x))
.to_output_stream())
}
fn cd(&self, args: EvaluatedStaticCommandArgs) -> Result<OutputStream, ShellError> {
fn cd(&self, args: EvaluatedWholeStreamCommandArgs) -> Result<OutputStream, ShellError> {
let path = match args.nth(0) {
None => "/".to_string(),
Some(v) => {