move out call info deserializing from str (#3294)

This commit is contained in:
Andrés N. Robalino
2021-04-09 22:58:18 -05:00
committed by GitHub
parent b19a7aa8a6
commit a131eddf54
28 changed files with 691 additions and 399 deletions

View File

@ -78,23 +78,27 @@ impl std::fmt::Debug for CommandArgs {
impl CommandArgs {
pub fn evaluate_once(self) -> Result<EvaluatedWholeStreamCommandArgs, ShellError> {
let ctx = EvaluationContext::from_args(&self);
let host = self.host.clone();
let ctrl_c = self.ctrl_c.clone();
let configs = self.configs.clone();
let shell_manager = self.shell_manager.clone();
let ctx = EvaluationContext::new(
self.scope,
self.host,
self.current_errors,
self.ctrl_c,
self.configs,
self.shell_manager,
Arc::new(Mutex::new(std::collections::HashMap::new())),
);
let input = self.input;
let call_info = self.call_info.evaluate(&ctx)?;
let scope = self.scope.clone();
Ok(EvaluatedWholeStreamCommandArgs::new(
host,
ctrl_c,
configs,
shell_manager,
ctx.host,
ctx.ctrl_c,
ctx.configs,
ctx.shell_manager,
call_info,
input,
scope,
ctx.scope,
))
}
@ -112,6 +116,15 @@ impl CommandArgs {
(self.input, new_context)
}
pub fn extract<T>(
self,
f: impl FnOnce(&EvaluatedCommandArgs) -> Result<T, ShellError>,
) -> Result<(T, InputStream), ShellError> {
let evaluated_args = self.evaluate_once()?;
Ok((f(&evaluated_args.args)?, evaluated_args.input))
}
pub fn process<'de, T: Deserialize<'de>>(self) -> Result<(T, InputStream), ShellError> {
let args = self.evaluate_once()?;
let call_info = args.call_info.clone();
@ -205,6 +218,13 @@ impl EvaluatedCommandArgs {
.map(|x| FromValue::from_value(x))
}
pub fn req_named<T: FromValue>(&self, name: &str) -> Result<T, ShellError> {
self.call_info
.args
.expect_get(name)
.and_then(|x| FromValue::from_value(x))
}
pub fn has_flag(&self, name: &str) -> bool {
self.call_info.args.has(name)
}
@ -229,6 +249,10 @@ impl EvaluatedCommandArgs {
}
}
pub fn rest_args<T: FromValue>(&self) -> Result<Vec<T>, ShellError> {
self.rest(0)
}
pub fn rest<T: FromValue>(&self, starting_pos: usize) -> Result<Vec<T>, ShellError> {
let mut output = vec![];

View File

@ -22,6 +22,12 @@ pub trait Host: Debug + Send {
fn is_external_cmd(&self, cmd_name: &str) -> bool;
}
impl Default for Box<dyn Host> {
fn default() -> Self {
Box::new(BasicHost)
}
}
impl Host for Box<dyn Host> {
fn stdout(&mut self, out: &str) {
(**self).stdout(out)

View File

@ -14,7 +14,7 @@ use parking_lot::Mutex;
use std::sync::atomic::AtomicBool;
use std::{path::Path, sync::Arc};
#[derive(Clone)]
#[derive(Clone, Default)]
pub struct EvaluationContext {
pub scope: Scope,
pub host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
@ -28,6 +28,26 @@ pub struct EvaluationContext {
}
impl EvaluationContext {
pub fn new(
scope: Scope,
host: Arc<parking_lot::Mutex<Box<dyn Host>>>,
current_errors: Arc<Mutex<Vec<ShellError>>>,
ctrl_c: Arc<AtomicBool>,
configs: Arc<Mutex<ConfigHolder>>,
shell_manager: ShellManager,
windows_drives_previous_cwd: Arc<Mutex<std::collections::HashMap<String, String>>>,
) -> Self {
Self {
scope,
host,
current_errors,
ctrl_c,
configs,
shell_manager,
windows_drives_previous_cwd,
}
}
pub fn from_args(args: &CommandArgs) -> EvaluationContext {
EvaluationContext {
scope: args.scope.clone(),

View File

@ -40,6 +40,12 @@ impl FromValue for num_bigint::BigInt {
}
}
}
impl FromValue for Tagged<u64> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
let tag = v.tag.clone();
v.as_u64().map(|s| s.tagged(tag))
}
}
impl FromValue for u64 {
fn from_value(v: &Value) -> Result<Self, ShellError> {
@ -47,6 +53,34 @@ impl FromValue for u64 {
}
}
impl FromValue for Tagged<u32> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
let tag = v.tag.clone();
v.as_u32().map(|s| s.tagged(tag))
}
}
impl FromValue for Tagged<i16> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
let tag = v.tag.clone();
v.as_i16().map(|s| s.tagged(tag))
}
}
impl FromValue for Tagged<usize> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
let tag = v.tag.clone();
v.as_usize().map(|s| s.tagged(tag))
}
}
impl FromValue for Tagged<char> {
fn from_value(v: &Value) -> Result<Self, ShellError> {
let tag = v.tag.clone();
v.as_char().map(|c| c.tagged(tag))
}
}
impl FromValue for usize {
fn from_value(v: &Value) -> Result<Self, ShellError> {
v.as_usize()

View File

@ -12,7 +12,7 @@ use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;
#[derive(Clone, Debug)]
#[derive(Clone, Default, Debug)]
pub struct ShellManager {
pub current_shell: Arc<AtomicUsize>,
pub shells: Arc<Mutex<Vec<Box<dyn Shell + Send>>>>,