Continue prepping for object streams

This commit is contained in:
Yehuda Katz 2019-05-11 15:59:57 -07:00
parent aa3fe0b0db
commit e6da37f5be
8 changed files with 70 additions and 21 deletions

View File

@ -1,3 +1,4 @@
crate mod args;
crate mod cd; crate mod cd;
crate mod command; crate mod command;
crate mod ls; crate mod ls;

View File

@ -1,6 +1,31 @@
use crate::Value; use crate::object::Value;
use derive_new::new;
use std::collections::VecDeque;
#[derive(Debug, Clone)] #[derive(Debug, Default)]
pub struct Args { pub struct ObjectStream {
args: Vec<Value>, queue: VecDeque<Value>,
}
#[derive(Debug, Default)]
pub struct Streams {
success: ObjectStream,
error: ObjectStream,
warning: ObjectStream,
debug: ObjectStream,
trace: ObjectStream,
verbose: ObjectStream,
}
#[derive(Debug, new)]
pub struct Args {
argv: Vec<Value>,
#[new(default)]
streams: Streams,
}
impl Args {
crate fn first(&self) -> Option<&Value> {
self.argv.first()
}
} }

View File

@ -1,6 +1,7 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::process::Process; use crate::object::process::Process;
use crate::object::{DirEntry, ShellObject, Value}; use crate::object::{DirEntry, ShellObject, Value};
use crate::Args;
use derive_new::new; use derive_new::new;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use sysinfo::SystemExt; use sysinfo::SystemExt;
@ -11,14 +12,20 @@ pub struct CdBlueprint;
impl crate::CommandBlueprint for CdBlueprint { impl crate::CommandBlueprint for CdBlueprint {
fn create( fn create(
&self, &self,
args: Vec<String>, args: Args,
host: &dyn crate::Host, host: &dyn crate::Host,
env: &mut crate::Environment, env: &mut crate::Environment,
) -> Box<dyn crate::Command> { ) -> Result<Box<dyn crate::Command>, ShellError> {
Box::new(Cd { let target = match args.first() {
// TODO: This needs better infra
None => return Err(ShellError::new(format!("cd must take one arg"))),
Some(v) => v.as_string()?.clone(),
};
Ok(Box::new(Cd {
cwd: env.cwd().to_path_buf(), cwd: env.cwd().to_path_buf(),
target: args[0].clone(), target,
}) }))
} }
} }

View File

@ -5,10 +5,10 @@ use std::path::PathBuf;
pub trait CommandBlueprint { pub trait CommandBlueprint {
fn create( fn create(
&self, &self,
args: Vec<String>, args: crate::Args,
host: &dyn crate::Host, host: &dyn crate::Host,
env: &mut crate::Environment, env: &mut crate::Environment,
) -> Box<dyn Command>; ) -> Result<Box<dyn Command>, ShellError>;
} }
crate enum CommandAction { crate enum CommandAction {

View File

@ -1,6 +1,7 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::process::Process; use crate::object::process::Process;
use crate::object::{DirEntry, ShellObject, Value}; use crate::object::{DirEntry, ShellObject, Value};
use crate::Args;
use crate::{Command, CommandSuccess}; use crate::{Command, CommandSuccess};
use derive_new::new; use derive_new::new;
use std::path::PathBuf; use std::path::PathBuf;
@ -12,13 +13,13 @@ pub struct LsBlueprint;
impl crate::CommandBlueprint for LsBlueprint { impl crate::CommandBlueprint for LsBlueprint {
fn create( fn create(
&self, &self,
args: Vec<String>, args: Args,
host: &dyn crate::Host, host: &dyn crate::Host,
env: &mut crate::Environment, env: &mut crate::Environment,
) -> Box<dyn Command> { ) -> Result<Box<dyn Command>, ShellError> {
Box::new(Ls { Ok(Box::new(Ls {
cwd: env.cwd().to_path_buf(), cwd: env.cwd().to_path_buf(),
}) }))
} }
} }

View File

@ -15,11 +15,11 @@ pub struct PsBlueprint {
impl crate::CommandBlueprint for PsBlueprint { impl crate::CommandBlueprint for PsBlueprint {
fn create( fn create(
&self, &self,
args: Vec<String>, args: crate::Args,
host: &dyn crate::Host, host: &dyn crate::Host,
env: &mut crate::Environment, env: &mut crate::Environment,
) -> Box<dyn Command> { ) -> Result<Box<dyn Command>, ShellError> {
Box::new(Ps::new(self.system.clone())) Ok(Box::new(Ps::new(self.system.clone())))
} }
} }

View File

@ -9,11 +9,14 @@ mod format;
mod object; mod object;
mod parser; mod parser;
crate use crate::commands::args::{Args, Streams};
crate use crate::commands::command::{Command, CommandAction, CommandBlueprint, CommandSuccess}; crate use crate::commands::command::{Command, CommandAction, CommandBlueprint, CommandSuccess};
crate use crate::env::{Environment, Host}; crate use crate::env::{Environment, Host};
crate use crate::errors::ShellError; crate use crate::errors::ShellError;
crate use crate::format::RenderView; crate use crate::format::RenderView;
use crate::object::base::{ToEntriesView, ToGenericView}; use crate::object::base::{ToEntriesView, ToGenericView};
use crate::object::Value;
use ansi_term::Color; use ansi_term::Color;
use conch_parser::lexer::Lexer; use conch_parser::lexer::Lexer;
use conch_parser::parse::DefaultParser; use conch_parser::parse::DefaultParser;
@ -81,14 +84,16 @@ fn main() -> Result<(), Box<Error>> {
} }
let command = &parsed[0][0].name(); let command = &parsed[0][0].name();
let args = parsed[0][1..] let arg_list = parsed[0][1..]
.iter() .iter()
.map(|i| i.name().to_string()) .map(|i| Value::string(i.name().to_string()))
.collect(); .collect();
let args = Args::new(arg_list);
match commands.get_mut(*command) { match commands.get_mut(*command) {
Some(command) => { Some(command) => {
let mut instance = command.create(args, &mut host, &mut env); let mut instance = command.create(args, &mut host, &mut env)?;
let result = instance.run()?; let result = instance.run()?;
for action in result.action { for action in result.action {

View File

@ -1,3 +1,4 @@
use crate::errors::ShellError;
use crate::format::{EntriesView, GenericView}; use crate::format::{EntriesView, GenericView};
use crate::object::desc::DataDescriptor; use crate::object::desc::DataDescriptor;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
@ -67,6 +68,15 @@ impl Value {
} }
} }
crate fn as_string(&self) -> Result<String, ShellError> {
match self {
Value::Primitive(Primitive::String(s)) => Ok(s.to_string()),
// TODO: this should definitely be more general with better errors
other => Err(ShellError::new(format!("Expected string, got {:?}", other))),
}
}
crate fn string(s: impl Into<String>) -> Value { crate fn string(s: impl Into<String>) -> Value {
Value::Primitive(Primitive::String(s.into())) Value::Primitive(Primitive::String(s.into()))
} }