Get stream errors working

This commit is contained in:
Jonathan Turner 2019-06-16 05:52:55 +12:00
parent a3c3c4d776
commit 910869b79d
13 changed files with 68 additions and 27 deletions

View File

@ -113,7 +113,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
let (obj, cwd) = { let (obj, cwd) = {
let env = context.env.lock().unwrap(); let env = context.env.lock().unwrap();
let last = env.last().unwrap(); let last = env.back().unwrap();
(last.obj().clone(), last.path().display().to_string()) (last.obj().clone(), last.path().display().to_string())
}; };
let readline = match obj { let readline = match obj {

View File

@ -5,7 +5,7 @@ use std::path::PathBuf;
pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
let env = args.env.lock().unwrap(); let env = args.env.lock().unwrap();
let latest = env.last().unwrap(); let latest = env.back().unwrap();
match latest.obj { match latest.obj {
Value::Filesystem => { Value::Filesystem => {

View File

@ -4,6 +4,7 @@ use crate::parser::lexer::Span;
use crate::parser::registry::Args; use crate::parser::registry::Args;
use crate::prelude::*; use crate::prelude::*;
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use futures::stream::StreamExt;
use futures_codec::{Decoder, Encoder, Framed}; use futures_codec::{Decoder, Encoder, Framed};
use std::io::{Error, ErrorKind}; use std::io::{Error, ErrorKind};
use std::path::PathBuf; use std::path::PathBuf;
@ -109,15 +110,50 @@ impl InternalCommand {
context: &mut Context, context: &mut Context,
input: ClassifiedInputStream, input: ClassifiedInputStream,
) -> Result<InputStream, ShellError> { ) -> Result<InputStream, ShellError> {
let result = context.run_command( let mut result = context.run_command(
self.command, self.command,
self.name_span.clone(), self.name_span.clone(),
self.args, self.args,
input.objects, input.objects,
)?; )?;
let env = context.env.clone(); let mut stream = VecDeque::new();
while let Some(item) = result.next().await {
match item {
ReturnValue::Value(Value::Error(err)) => {
return Err(*err);
}
ReturnValue::Action(action) => match action {
CommandAction::ChangePath(path) => {
context.env.lock().unwrap().back_mut().map(|x| {
x.path = path;
x
});
}
CommandAction::Enter(obj) => {
let new_env = Environment {
obj: obj,
path: PathBuf::from("/"),
};
context.env.lock().unwrap().push_back(new_env);
}
CommandAction::Exit => match context.env.lock().unwrap().pop_back() {
Some(Environment {
obj: Value::Filesystem,
..
}) => std::process::exit(0),
None => std::process::exit(-1),
_ => {}
},
},
ReturnValue::Value(v) => {
stream.push_back(v);
}
}
}
/*
let stream = result.filter_map(move |v| match v { let stream = result.filter_map(move |v| match v {
//ReturnValue::Value(Value::Error(err)) => futures::future::err(Err(err)),
ReturnValue::Action(action) => match action { ReturnValue::Action(action) => match action {
CommandAction::ChangePath(path) => { CommandAction::ChangePath(path) => {
env.lock().unwrap().last_mut().map(|x| { env.lock().unwrap().last_mut().map(|x| {
@ -146,7 +182,7 @@ impl InternalCommand {
ReturnValue::Value(v) => futures::future::ready(Some(v)), ReturnValue::Value(v) => futures::future::ready(Some(v)),
}); });
*/
Ok(stream.boxed() as InputStream) Ok(stream.boxed() as InputStream)
} }
} }
@ -229,7 +265,7 @@ impl ExternalCommand {
} }
process = Exec::shell(new_arg_string); process = Exec::shell(new_arg_string);
} }
process = process.cwd(context.env.lock().unwrap().first().unwrap().path()); process = process.cwd(context.env.lock().unwrap().front().unwrap().path());
let mut process = match stream_next { let mut process = match stream_next {
StreamNext::Last => process, StreamNext::Last => process,

View File

@ -8,7 +8,7 @@ use std::path::PathBuf;
pub struct CommandArgs { pub struct CommandArgs {
pub host: Arc<Mutex<dyn Host + Send>>, pub host: Arc<Mutex<dyn Host + Send>>,
pub env: Arc<Mutex<Vec<Environment>>>, pub env: Arc<Mutex<VecDeque<Environment>>>,
pub name_span: Option<Span>, pub name_span: Option<Span>,
pub positional: Vec<Spanned<Value>>, pub positional: Vec<Spanned<Value>>,
pub named: indexmap::IndexMap<String, Value>, pub named: indexmap::IndexMap<String, Value>,

View File

@ -14,7 +14,7 @@ pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
.env .env
.lock() .lock()
.unwrap() .unwrap()
.first() .front()
.unwrap() .unwrap()
.path() .path()
.to_path_buf(); .to_path_buf();

View File

@ -1,11 +1,8 @@
use crate::commands::command::CommandAction; use crate::commands::command::CommandAction;
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::lexer::Spanned;
use crate::prelude::*; use crate::prelude::*;
use std::path::{Path, PathBuf};
pub fn exit(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn exit(_args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut stream = VecDeque::new(); let mut stream = VecDeque::new();
stream.push_back(ReturnValue::Action(CommandAction::Exit)); stream.push_back(ReturnValue::Action(CommandAction::Exit));
Ok(stream.boxed()) Ok(stream.boxed())

View File

@ -1,17 +1,19 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::Value; use crate::object::Value;
use crate::parser::lexer::Span;
use crate::prelude::*; use crate::prelude::*;
fn get_member(path: &str, obj: &Value) -> Option<Value> { fn get_member(path: &str, span: Span, obj: &Value) -> Option<Value> {
let mut current = obj; let mut current = obj;
for p in path.split(".") { for p in path.split(".") {
match current.get_data_by_key(p) { match current.get_data_by_key(p) {
Some(v) => current = v, Some(v) => current = v,
None => { None => {
return Some(Value::Error(Box::new(ShellError::string(format!( return Some(Value::Error(Box::new(ShellError::labeled_error(
"Object field name not found: {}", "Unknown field",
p "unknown field",
))))) span,
))));
} }
} }
} }
@ -44,7 +46,11 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
.boxed()); .boxed());
} }
let fields: Result<Vec<String>, _> = args.positional.iter().map(|a| a.as_string()).collect(); let fields: Result<Vec<(String, Span)>, _> = args
.positional
.iter()
.map(|a| (a.as_string().map(|x| (x, a.span))))
.collect();
let fields = fields?; let fields = fields?;
let stream = args let stream = args
@ -52,7 +58,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(move |item| { .map(move |item| {
let mut result = VecDeque::new(); let mut result = VecDeque::new();
for field in &fields { for field in &fields {
match get_member(field, &item) { match get_member(&field.0, field.1, &item) {
Some(Value::List(l)) => { Some(Value::List(l)) => {
for item in l { for item in l {
result.push_back(ReturnValue::Value(item.copy())); result.push_back(ReturnValue::Value(item.copy()));

View File

@ -7,8 +7,8 @@ use std::path::{Path, PathBuf};
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
let env = args.env.lock().unwrap(); let env = args.env.lock().unwrap();
let path = env.last().unwrap().path.to_path_buf(); let path = env.back().unwrap().path.to_path_buf();
let obj = &env.last().unwrap().obj; let obj = &env.back().unwrap().obj;
let mut full_path = PathBuf::from(path); let mut full_path = PathBuf::from(path);
match &args.positional.get(0) { match &args.positional.get(0) {
Some(Spanned { Some(Spanned {

View File

@ -13,7 +13,7 @@ pub fn open(args: CommandArgs) -> Result<OutputStream, ShellError> {
.env .env
.lock() .lock()
.unwrap() .unwrap()
.first() .front()
.unwrap() .unwrap()
.path() .path()
.to_path_buf(); .to_path_buf();

View File

@ -14,7 +14,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
.env .env
.lock() .lock()
.unwrap() .unwrap()
.first() .front()
.unwrap() .unwrap()
.path() .path()
.to_path_buf(); .to_path_buf();

View File

@ -13,7 +13,7 @@ pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
.env .env
.lock() .lock()
.unwrap() .unwrap()
.first() .front()
.unwrap() .unwrap()
.path() .path()
.to_path_buf(); .to_path_buf();

View File

@ -34,7 +34,7 @@ pub fn view(args: CommandArgs) -> Result<OutputStream, ShellError> {
.env .env
.lock() .lock()
.unwrap() .unwrap()
.first() .front()
.unwrap() .unwrap()
.path() .path()
.to_path_buf(); .to_path_buf();

View File

@ -13,16 +13,18 @@ pub struct Context {
commands: IndexMap<String, Arc<dyn Command>>, commands: IndexMap<String, Arc<dyn Command>>,
sinks: IndexMap<String, Arc<dyn Sink>>, sinks: IndexMap<String, Arc<dyn Sink>>,
crate host: Arc<Mutex<dyn Host + Send>>, crate host: Arc<Mutex<dyn Host + Send>>,
crate env: Arc<Mutex<Vec<Environment>>>, crate env: Arc<Mutex<VecDeque<Environment>>>,
} }
impl Context { impl Context {
crate fn basic() -> Result<Context, Box<dyn Error>> { crate fn basic() -> Result<Context, Box<dyn Error>> {
let mut env = VecDeque::new();
env.push_back(Environment::basic()?);
Ok(Context { Ok(Context {
commands: indexmap::IndexMap::new(), commands: indexmap::IndexMap::new(),
sinks: indexmap::IndexMap::new(), sinks: indexmap::IndexMap::new(),
host: Arc::new(Mutex::new(crate::env::host::BasicHost)), host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
env: Arc::new(Mutex::new(vec![Environment::basic()?])), env: Arc::new(Mutex::new(env)),
}) })
} }