mirror of
https://github.com/nushell/nushell
synced 2024-11-10 07:04:13 +00:00
A bunch of rework
I'm gonna use a VecDeque now instead of trying to get async streams working to make progress, but the intent is that we should be able to use async streams in and out to interleave the work better.
This commit is contained in:
parent
786da8fd9d
commit
ceb0487eba
13 changed files with 177 additions and 74 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -254,6 +254,19 @@ name = "fuchsia-cprng"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures"
|
||||||
|
version = "0.1.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
@ -372,6 +385,8 @@ dependencies = [
|
||||||
"conch-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"conch-parser 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dunce 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nom 5.0.0-beta1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -751,6 +766,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||||
|
"checksum futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "a2037ec1c6c1c4f79557762eab1f7eae1f64f6cb418ace90fae88f0942b60139"
|
||||||
|
"checksum futures-core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7455c91eb2eae38f33b013f77ebe766c75761af333efd9d550e154045c63e225"
|
||||||
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
||||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||||
|
|
|
@ -19,3 +19,5 @@ conch-parser = "0.1.0"
|
||||||
nom = "5.0.0-beta1"
|
nom = "5.0.0-beta1"
|
||||||
subprocess = "0.1.18"
|
subprocess = "0.1.18"
|
||||||
dunce = "1.0.0"
|
dunce = "1.0.0"
|
||||||
|
futures = "0.1.27"
|
||||||
|
futures-core = "0.2.1"
|
||||||
|
|
|
@ -81,3 +81,12 @@ cd target
|
||||||
cd ..
|
cd ..
|
||||||
cd target
|
cd target
|
||||||
ls
|
ls
|
||||||
|
git status
|
||||||
|
git add .
|
||||||
|
git commit
|
||||||
|
git push
|
||||||
|
cd target
|
||||||
|
cd ..
|
||||||
|
exit
|
||||||
|
ls
|
||||||
|
ps
|
||||||
|
|
|
@ -3,3 +3,5 @@ crate mod cd;
|
||||||
crate mod command;
|
crate mod command;
|
||||||
crate mod ls;
|
crate mod ls;
|
||||||
crate mod ps;
|
crate mod ps;
|
||||||
|
|
||||||
|
crate use command::Command;
|
||||||
|
|
|
@ -1,20 +1,60 @@
|
||||||
use crate::object::Value;
|
use crate::object::Value;
|
||||||
|
use crate::ShellError;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
pub struct ObjectStream {
|
pub enum LogLevel {
|
||||||
queue: VecDeque<Value>,
|
Trace,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
Fatal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct LogItem {
|
||||||
|
level: LogLevel,
|
||||||
|
value: Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ObjectStream<T> {
|
||||||
|
queue: VecDeque<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ObjectStream<T> {
|
||||||
|
crate fn empty() -> ObjectStream<T> {
|
||||||
|
ObjectStream {
|
||||||
|
queue: VecDeque::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn iter(&self) -> impl Iterator<Item = &T> {
|
||||||
|
self.queue.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn take(&mut self) -> Option<T> {
|
||||||
|
self.queue.pop_front()
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn add(&mut self, value: T) {
|
||||||
|
self.queue.push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(new)]
|
||||||
pub struct Streams {
|
pub struct Streams {
|
||||||
success: Cell<ObjectStream>,
|
#[new(value = "ObjectStream::empty()")]
|
||||||
// error: ObjectStream,
|
success: ObjectStream<Value>,
|
||||||
// warning: ObjectStream,
|
|
||||||
// debug: ObjectStream,
|
#[new(value = "ObjectStream::empty()")]
|
||||||
// trace: ObjectStream,
|
errors: ObjectStream<ShellError>,
|
||||||
// verbose: ObjectStream,
|
|
||||||
|
#[new(value = "ObjectStream::empty()")]
|
||||||
|
log: ObjectStream<LogItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for Streams {
|
impl std::fmt::Debug for Streams {
|
||||||
|
@ -24,16 +64,12 @@ impl std::fmt::Debug for Streams {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Streams {
|
impl Streams {
|
||||||
crate fn new() -> Streams {
|
crate fn read(&mut self) -> Option<Value> {
|
||||||
Streams {
|
self.success.take()
|
||||||
success: Cell::new(ObjectStream::default()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn take_success(&mut self) -> Cell<ObjectStream> {
|
crate fn add(&mut self, value: Value) {
|
||||||
let new_stream = Cell::new(ObjectStream::default());
|
self.success.add(value);
|
||||||
self.success.swap(&new_stream);
|
|
||||||
new_stream
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn take_stream(&mut self, stream: &mut ObjectStream) -> ObjectStream {
|
// fn take_stream(&mut self, stream: &mut ObjectStream) -> ObjectStream {
|
||||||
|
|
|
@ -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::prelude::*;
|
||||||
use crate::Args;
|
use crate::Args;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -12,13 +13,13 @@ pub struct CdBlueprint;
|
||||||
impl crate::CommandBlueprint for CdBlueprint {
|
impl crate::CommandBlueprint for CdBlueprint {
|
||||||
fn create(
|
fn create(
|
||||||
&self,
|
&self,
|
||||||
args: Args,
|
args: Vec<Value>,
|
||||||
host: &dyn crate::Host,
|
host: &dyn Host,
|
||||||
env: &mut crate::Environment,
|
env: &mut Environment,
|
||||||
) -> Result<Box<dyn crate::Command>, ShellError> {
|
) -> Result<Box<dyn Command>, ShellError> {
|
||||||
let target = match args.first() {
|
let target = match args.first() {
|
||||||
// TODO: This needs better infra
|
// TODO: This needs better infra
|
||||||
None => return Err(ShellError::new(format!("cd must take one arg"))),
|
None => return Err(ShellError::string(format!("cd must take one arg"))),
|
||||||
Some(v) => v.as_string()?.clone(),
|
Some(v) => v.as_string()?.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,12 +37,10 @@ pub struct Cd {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Command for Cd {
|
impl crate::Command for Cd {
|
||||||
fn run(&mut self) -> Result<crate::CommandSuccess, ShellError> {
|
fn run(&mut self, stream: VecDeque<Value>) -> Result<VecDeque<ReturnValue>, ShellError> {
|
||||||
Ok(crate::CommandSuccess {
|
let mut stream = VecDeque::new();
|
||||||
value: Value::nothing(),
|
let path = dunce::canonicalize(self.cwd.join(&self.target).as_path())?;
|
||||||
action: vec![crate::CommandAction::ChangeCwd(dunce::canonicalize(
|
stream.push_back(ReturnValue::change_cwd(path));
|
||||||
self.cwd.join(&self.target).as_path(),
|
Ok(stream)
|
||||||
)?)],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,38 @@
|
||||||
use crate::errors::ShellError;
|
use crate::errors::ShellError;
|
||||||
use crate::object::Value;
|
use crate::object::Value;
|
||||||
|
use crate::prelude::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub trait CommandBlueprint {
|
pub trait CommandBlueprint {
|
||||||
fn create(
|
fn create(
|
||||||
&self,
|
&self,
|
||||||
input: crate::Args,
|
input: Vec<Value>,
|
||||||
host: &dyn crate::Host,
|
host: &dyn crate::Host,
|
||||||
env: &mut crate::Environment,
|
env: &mut crate::Environment,
|
||||||
) -> Result<Box<dyn Command>, ShellError>;
|
) -> Result<Box<dyn Command>, ShellError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate enum CommandAction {
|
pub enum CommandAction {
|
||||||
ChangeCwd(PathBuf),
|
ChangeCwd(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CommandSuccess {
|
pub enum ReturnValue {
|
||||||
crate value: Value,
|
Value(Value),
|
||||||
crate action: Vec<CommandAction>,
|
Action(CommandAction),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReturnValue {
|
||||||
|
crate fn single(value: Value) -> VecDeque<ReturnValue> {
|
||||||
|
let mut v = VecDeque::new();
|
||||||
|
v.push_back(ReturnValue::Value(value));
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn change_cwd(path: PathBuf) -> ReturnValue {
|
||||||
|
ReturnValue::Action(CommandAction::ChangeCwd(path))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Command {
|
pub trait Command {
|
||||||
fn begin(&mut self) -> Result<(), ShellError> {
|
fn run(&mut self, stream: VecDeque<Value>) -> Result<VecDeque<ReturnValue>, ShellError>;
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
fn run(&mut self) -> Result<CommandSuccess, ShellError>;
|
|
||||||
fn end(&mut self) -> Result<(), ShellError> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
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::prelude::*;
|
||||||
use crate::Args;
|
use crate::Args;
|
||||||
use crate::{Command, CommandSuccess};
|
use crate::Command;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use sysinfo::SystemExt;
|
use sysinfo::SystemExt;
|
||||||
|
@ -13,7 +14,7 @@ pub struct LsBlueprint;
|
||||||
impl crate::CommandBlueprint for LsBlueprint {
|
impl crate::CommandBlueprint for LsBlueprint {
|
||||||
fn create(
|
fn create(
|
||||||
&self,
|
&self,
|
||||||
args: Args,
|
args: Vec<Value>,
|
||||||
host: &dyn crate::Host,
|
host: &dyn crate::Host,
|
||||||
env: &mut crate::Environment,
|
env: &mut crate::Environment,
|
||||||
) -> Result<Box<dyn Command>, ShellError> {
|
) -> Result<Box<dyn Command>, ShellError> {
|
||||||
|
@ -29,20 +30,17 @@ pub struct Ls {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Command for Ls {
|
impl crate::Command for Ls {
|
||||||
fn run(&mut self) -> Result<CommandSuccess, ShellError> {
|
fn run(&mut self, stream: VecDeque<Value>) -> Result<VecDeque<ReturnValue>, ShellError> {
|
||||||
let entries =
|
let entries =
|
||||||
std::fs::read_dir(&self.cwd).map_err((|e| ShellError::new(format!("{:?}", e))))?;
|
std::fs::read_dir(&self.cwd).map_err((|e| ShellError::string(format!("{:?}", e))))?;
|
||||||
|
|
||||||
let mut shell_entries = vec![];
|
let mut shell_entries = VecDeque::new();
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let value = Value::object(DirEntry::new(entry?)?);
|
let value = Value::object(DirEntry::new(entry?)?);
|
||||||
shell_entries.push(value)
|
shell_entries.push_back(ReturnValue::Value(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CommandSuccess {
|
Ok(shell_entries)
|
||||||
value: Value::list(shell_entries),
|
|
||||||
action: vec![],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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::{ShellObject, Value};
|
use crate::object::{ShellObject, Value};
|
||||||
|
use crate::prelude::*;
|
||||||
use crate::Command;
|
use crate::Command;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -15,7 +16,7 @@ pub struct PsBlueprint {
|
||||||
impl crate::CommandBlueprint for PsBlueprint {
|
impl crate::CommandBlueprint for PsBlueprint {
|
||||||
fn create(
|
fn create(
|
||||||
&self,
|
&self,
|
||||||
args: crate::Args,
|
args: Vec<Value>,
|
||||||
host: &dyn crate::Host,
|
host: &dyn crate::Host,
|
||||||
env: &mut crate::Environment,
|
env: &mut crate::Environment,
|
||||||
) -> Result<Box<dyn Command>, ShellError> {
|
) -> Result<Box<dyn Command>, ShellError> {
|
||||||
|
@ -29,7 +30,7 @@ pub struct Ps {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Command for Ps {
|
impl crate::Command for Ps {
|
||||||
fn run(&mut self) -> Result<crate::CommandSuccess, ShellError> {
|
fn run(&mut self, stream: VecDeque<Value>) -> Result<VecDeque<ReturnValue>, ShellError> {
|
||||||
let mut system = self.system.borrow_mut();
|
let mut system = self.system.borrow_mut();
|
||||||
system.refresh_all();
|
system.refresh_all();
|
||||||
|
|
||||||
|
@ -37,13 +38,12 @@ impl crate::Command for Ps {
|
||||||
|
|
||||||
let list = list
|
let list = list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, process)| Value::Object(Box::new(Process::new(process.clone()))))
|
.map(|(_, process)| {
|
||||||
|
ReturnValue::Value(Value::Object(Box::new(Process::new(process.clone()))))
|
||||||
|
})
|
||||||
.take(5)
|
.take(5)
|
||||||
.collect();
|
.collect::<VecDeque<_>>();
|
||||||
|
|
||||||
Ok(crate::CommandSuccess {
|
Ok(list)
|
||||||
value: Value::List(list),
|
|
||||||
action: vec![],
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
|
use crate::Value;
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
|
|
||||||
#[derive(Debug, new)]
|
#[derive(Debug, new)]
|
||||||
pub struct ShellError {
|
pub struct ShellError {
|
||||||
title: String,
|
title: String,
|
||||||
|
error: Value,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShellError {
|
||||||
|
crate fn string(title: impl Into<String>) -> ShellError {
|
||||||
|
ShellError::new(title.into(), Value::nothing())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ShellError {
|
impl std::fmt::Display for ShellError {
|
||||||
|
@ -17,6 +25,7 @@ impl std::convert::From<std::io::Error> for ShellError {
|
||||||
fn from(input: std::io::Error) -> ShellError {
|
fn from(input: std::io::Error) -> ShellError {
|
||||||
ShellError {
|
ShellError {
|
||||||
title: format!("{}", input),
|
title: format!("{}", input),
|
||||||
|
error: Value::nothing(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -8,9 +8,11 @@ mod errors;
|
||||||
mod format;
|
mod format;
|
||||||
mod object;
|
mod object;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
mod prelude;
|
||||||
|
|
||||||
crate use crate::commands::args::{Args, Streams};
|
crate use crate::commands::args::{Args, Streams};
|
||||||
crate use crate::commands::command::{Command, CommandAction, CommandBlueprint, CommandSuccess};
|
use crate::commands::command::ReturnValue;
|
||||||
|
crate use crate::commands::command::{Command, CommandAction, CommandBlueprint};
|
||||||
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;
|
||||||
|
@ -24,6 +26,7 @@ use rustyline::error::ReadlineError;
|
||||||
use rustyline::Editor;
|
use rustyline::Editor;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use subprocess::Exec;
|
use subprocess::Exec;
|
||||||
|
@ -73,7 +76,7 @@ fn main() -> Result<(), Box<Error>> {
|
||||||
match readline {
|
match readline {
|
||||||
Ok(line) => {
|
Ok(line) => {
|
||||||
let result = crate::parser::shell_parser(&line)
|
let result = crate::parser::shell_parser(&line)
|
||||||
.map_err(|e| ShellError::new(format!("{:?}", e)))?;
|
.map_err(|e| ShellError::string(format!("{:?}", e)))?;
|
||||||
|
|
||||||
let parsed = result.1;
|
let parsed = result.1;
|
||||||
|
|
||||||
|
@ -89,26 +92,38 @@ fn main() -> Result<(), Box<Error>> {
|
||||||
.map(|i| Value::string(i.name().to_string()))
|
.map(|i| Value::string(i.name().to_string()))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let args = Args::new(arg_list);
|
let streams = Streams::new();
|
||||||
|
|
||||||
|
// 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(arg_list, &mut host, &mut env)?;
|
||||||
let result = instance.run()?;
|
|
||||||
|
|
||||||
for action in result.action {
|
let out = VecDeque::new();
|
||||||
match action {
|
|
||||||
crate::CommandAction::ChangeCwd(cwd) => env.cwd = cwd,
|
let mut result = instance.run(out)?;
|
||||||
|
let mut next = VecDeque::new();
|
||||||
|
|
||||||
|
for v in result {
|
||||||
|
match v {
|
||||||
|
ReturnValue::Action(action) => match action {
|
||||||
|
crate::CommandAction::ChangeCwd(cwd) => env.cwd = cwd,
|
||||||
|
},
|
||||||
|
|
||||||
|
ReturnValue::Value(v) => next.push_back(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let view = result.value.to_generic_view();
|
for item in next {
|
||||||
let rendered = view.render_view(&mut host);
|
let view = item.to_generic_view();
|
||||||
|
let rendered = view.render_view(&mut host);
|
||||||
|
|
||||||
for line in rendered {
|
for line in rendered {
|
||||||
match line.as_ref() {
|
match line.as_ref() {
|
||||||
"\n" => println!(""),
|
"\n" => println!(""),
|
||||||
line => println!("{}", line),
|
line => println!("{}", line),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,10 @@ impl Value {
|
||||||
Value::Primitive(Primitive::String(s)) => Ok(s.to_string()),
|
Value::Primitive(Primitive::String(s)) => Ok(s.to_string()),
|
||||||
|
|
||||||
// TODO: this should definitely be more general with better errors
|
// TODO: this should definitely be more general with better errors
|
||||||
other => Err(ShellError::new(format!("Expected string, got {:?}", other))),
|
other => Err(ShellError::string(format!(
|
||||||
|
"Expected string, got {:?}",
|
||||||
|
other
|
||||||
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
6
src/prelude.rs
Normal file
6
src/prelude.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
crate use crate::commands::args::{Args, Streams};
|
||||||
|
crate use crate::commands::command::{Command, CommandAction, CommandBlueprint, ReturnValue};
|
||||||
|
crate use crate::env::{Environment, Host};
|
||||||
|
crate use crate::errors::ShellError;
|
||||||
|
crate use crate::format::RenderView;
|
||||||
|
crate use std::collections::VecDeque;
|
Loading…
Reference in a new issue