Prep for streaming objects

This commit is contained in:
Yehuda Katz 2019-05-11 01:08:21 -07:00
parent 65f671333d
commit aa3fe0b0db
7 changed files with 147 additions and 39 deletions

View File

@ -64,3 +64,20 @@ ls
cargo cargo
cargo build cargo build
cargo run cargo run
git status
git add .
git commit
git push
git status
git add .
git commit
git push
git config --global core.autocrlf input
git config
ls
cd target
ls
cd target
cd ..
cd target
ls

6
src/commands/args.rs Normal file
View File

@ -0,0 +1,6 @@
use crate::Value;
#[derive(Debug, Clone)]
pub struct Args {
args: Vec<Value>,
}

View File

@ -6,16 +6,35 @@ use std::path::{Path, PathBuf};
use sysinfo::SystemExt; use sysinfo::SystemExt;
#[derive(new)] #[derive(new)]
pub struct Cd; pub struct CdBlueprint;
impl crate::CommandBlueprint for CdBlueprint {
fn create(
&self,
args: Vec<String>,
host: &dyn crate::Host,
env: &mut crate::Environment,
) -> Box<dyn crate::Command> {
Box::new(Cd {
cwd: env.cwd().to_path_buf(),
target: args[0].clone(),
})
}
}
#[derive(new)]
pub struct Cd {
cwd: PathBuf,
target: String,
}
impl crate::Command for Cd { impl crate::Command for Cd {
fn run( fn run(&mut self) -> Result<crate::CommandSuccess, ShellError> {
&mut self, Ok(crate::CommandSuccess {
args: Vec<String>, value: Value::nothing(),
_host: &dyn crate::Host, action: vec![crate::CommandAction::ChangeCwd(dunce::canonicalize(
env: &mut crate::Environment, self.cwd.join(&self.target).as_path(),
) -> Result<Value, ShellError> { )?)],
env.cwd = dunce::canonicalize(env.cwd().join(&args[0]).as_path())?; })
Ok(Value::nothing())
} }
} }

View File

@ -1,11 +1,31 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use std::path::PathBuf;
pub trait Command { pub trait CommandBlueprint {
fn run( fn create(
&mut self, &self,
args: Vec<String>, args: Vec<String>,
host: &dyn crate::Host, host: &dyn crate::Host,
env: &mut crate::Environment, env: &mut crate::Environment,
) -> Result<Value, ShellError>; ) -> Box<dyn Command>;
}
crate enum CommandAction {
ChangeCwd(PathBuf),
}
pub struct CommandSuccess {
crate value: Value,
crate action: Vec<CommandAction>,
}
pub trait Command {
fn begin(&mut self) -> Result<(), ShellError> {
Ok(())
}
fn run(&mut self) -> Result<CommandSuccess, ShellError>;
fn end(&mut self) -> Result<(), ShellError> {
Ok(())
}
} }

View File

@ -1,21 +1,36 @@
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::{Command, CommandSuccess};
use derive_new::new; use derive_new::new;
use std::path::PathBuf;
use sysinfo::SystemExt; use sysinfo::SystemExt;
#[derive(new)] #[derive(new)]
pub struct Ls; pub struct LsBlueprint;
impl crate::CommandBlueprint for LsBlueprint {
fn create(
&self,
args: Vec<String>,
host: &dyn crate::Host,
env: &mut crate::Environment,
) -> Box<dyn Command> {
Box::new(Ls {
cwd: env.cwd().to_path_buf(),
})
}
}
#[derive(new)]
pub struct Ls {
cwd: PathBuf,
}
impl crate::Command for Ls { impl crate::Command for Ls {
fn run( fn run(&mut self) -> Result<CommandSuccess, ShellError> {
&mut self,
_args: Vec<String>,
_host: &dyn crate::Host,
env: &mut crate::Environment,
) -> Result<Value, ShellError> {
let entries = let entries =
std::fs::read_dir(env.cwd()).map_err((|e| ShellError::new(format!("{:?}", e))))?; std::fs::read_dir(&self.cwd).map_err((|e| ShellError::new(format!("{:?}", e))))?;
let mut shell_entries = vec![]; let mut shell_entries = vec![];
@ -24,6 +39,9 @@ impl crate::Command for Ls {
shell_entries.push(value) shell_entries.push(value)
} }
Ok(Value::list(shell_entries)) Ok(CommandSuccess {
value: Value::list(shell_entries),
action: vec![],
})
} }
} }

View File

@ -1,24 +1,39 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::process::Process; use crate::object::process::Process;
use crate::object::{ShellObject, Value}; use crate::object::{ShellObject, Value};
use crate::Command;
use derive_new::new; use derive_new::new;
use std::cell::RefCell;
use std::rc::Rc;
use sysinfo::SystemExt; use sysinfo::SystemExt;
#[derive(new)]
pub struct PsBlueprint {
system: Rc<RefCell<sysinfo::System>>,
}
impl crate::CommandBlueprint for PsBlueprint {
fn create(
&self,
args: Vec<String>,
host: &dyn crate::Host,
env: &mut crate::Environment,
) -> Box<dyn Command> {
Box::new(Ps::new(self.system.clone()))
}
}
#[derive(new)] #[derive(new)]
pub struct Ps { pub struct Ps {
system: sysinfo::System, system: Rc<RefCell<sysinfo::System>>,
} }
impl crate::Command for Ps { impl crate::Command for Ps {
fn run( fn run(&mut self) -> Result<crate::CommandSuccess, ShellError> {
&mut self, let mut system = self.system.borrow_mut();
_args: Vec<String>, system.refresh_all();
_host: &dyn crate::Host,
_env: &mut crate::Environment,
) -> Result<Value, ShellError> {
self.system.refresh_all();
let list = self.system.get_process_list(); let list = system.get_process_list();
let list = list let list = list
.into_iter() .into_iter()
@ -26,6 +41,9 @@ impl crate::Command for Ps {
.take(5) .take(5)
.collect(); .collect();
Ok(Value::List(list)) Ok(crate::CommandSuccess {
value: Value::List(list),
action: vec![],
})
} }
} }

View File

@ -9,7 +9,7 @@ mod format;
mod object; mod object;
mod parser; mod parser;
crate use crate::commands::command::Command; 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;
@ -19,8 +19,10 @@ use conch_parser::lexer::Lexer;
use conch_parser::parse::DefaultParser; use conch_parser::parse::DefaultParser;
use rustyline::error::ReadlineError; use rustyline::error::ReadlineError;
use rustyline::Editor; use rustyline::Editor;
use std::cell::RefCell;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::error::Error; use std::error::Error;
use std::rc::Rc;
use subprocess::Exec; use subprocess::Exec;
use sysinfo::{self, SystemExt}; use sysinfo::{self, SystemExt};
@ -48,12 +50,12 @@ fn main() -> Result<(), Box<Error>> {
let mut host = crate::env::host::BasicHost; let mut host = crate::env::host::BasicHost;
let mut env = crate::Environment::basic()?; let mut env = crate::Environment::basic()?;
let mut commands = BTreeMap::<String, Box<dyn crate::Command>>::new(); let mut commands = BTreeMap::<String, Box<dyn crate::CommandBlueprint>>::new();
let mut system = sysinfo::System::new(); let mut system = Rc::new(RefCell::new(sysinfo::System::new()));
let mut ps = crate::commands::ps::Ps::new(system); let mut ps = crate::commands::ps::PsBlueprint::new(system);
let mut ls = crate::commands::ls::Ls; let mut ls = crate::commands::ls::LsBlueprint;
let mut cd = crate::commands::cd::Cd; let mut cd = crate::commands::cd::CdBlueprint;
commands.insert("ps".to_string(), Box::new(ps)); commands.insert("ps".to_string(), Box::new(ps));
commands.insert("ls".to_string(), Box::new(ls)); commands.insert("ls".to_string(), Box::new(ls));
@ -86,8 +88,16 @@ fn main() -> Result<(), Box<Error>> {
match commands.get_mut(*command) { match commands.get_mut(*command) {
Some(command) => { Some(command) => {
let result = command.run(args, &mut host, &mut env).unwrap(); let mut instance = command.create(args, &mut host, &mut env);
let view = result.to_generic_view(); let result = instance.run()?;
for action in result.action {
match action {
crate::CommandAction::ChangeCwd(cwd) => env.cwd = cwd,
}
}
let view = result.value.to_generic_view();
let rendered = view.render_view(&mut host); let rendered = view.render_view(&mut host);
for line in rendered { for line in rendered {