Skip to content

Commit

Permalink
Fix: explicitly typed rest arguments handling in native library
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementNerma committed Dec 1, 2024
1 parent eb5aaf8 commit 3901470
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 42 deletions.
44 changes: 8 additions & 36 deletions crates/builtins/src/helpers/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use reshell_parser::ast::{
SingleValueType, ValueType,
};

use reshell_runtime::values::{CmdArgValue, RuntimeValue};
use reshell_runtime::values::RuntimeValue;

use crate::builder::internal_runtime_span;

Expand Down Expand Up @@ -69,7 +69,7 @@ pub trait ArgHandler {
fn min_unwrap<Z>(value: Option<Z>) -> Self::FixedOptionality<Z>;

type Parsed;
fn parse(&self, value: Self::FixedOptionality<RuntimeValue>) -> Result<Self::Parsed, ArgError>;
fn parse(&self, value: Self::FixedOptionality<RuntimeValue>) -> Result<Self::Parsed, String>;

type TypedValueParser: TypedValueParser;

Expand All @@ -78,12 +78,6 @@ pub trait ArgHandler {
}
}

#[derive(Debug)]
pub enum ArgError {
TypeError(String),
Panic(String),
}

pub struct Arg<const OPTIONAL: bool, T: TypedValueParser> {
names: ArgNames,
_t: PhantomData<T>,
Expand Down Expand Up @@ -144,8 +138,8 @@ impl<T: TypedValueParser> ArgHandler for Arg<false, T> {

type Parsed = T::Parsed;

fn parse(&self, value: RuntimeValue) -> Result<Self::Parsed, ArgError> {
T::parse(value).map_err(ArgError::TypeError)
fn parse(&self, value: RuntimeValue) -> Result<Self::Parsed, String> {
T::parse(value)
}

type TypedValueParser = T;
Expand All @@ -172,8 +166,8 @@ impl<T: TypedValueParser> ArgHandler for Arg<true, T> {

type Parsed = Option<T::Parsed>;

fn parse(&self, value: Option<RuntimeValue>) -> Result<Self::Parsed, ArgError> {
value.map(T::parse).transpose().map_err(ArgError::TypeError)
fn parse(&self, value: Option<RuntimeValue>) -> Result<Self::Parsed, String> {
value.map(T::parse).transpose()
}

type TypedValueParser = T;
Expand Down Expand Up @@ -214,30 +208,8 @@ impl<T: TypedValueParser> ArgHandler for RestArg<T> {

type Parsed = Vec<T::Parsed>;

fn parse(&self, value: RuntimeValue) -> Result<Self::Parsed, ArgError> {
match value {
RuntimeValue::List(values) => values
.read_promise_no_write()
.iter()
.enumerate()
.map(|(i, value)| match value {
RuntimeValue::CmdArg(arg) => match arg.as_ref() {
CmdArgValue::Basic(loc_val) => T::parse(loc_val.value.clone())
.map_err(|err| {
ArgError::TypeError(format!("in list item {}: {err}", i + 1))
}),

CmdArgValue::Flag(_) => Err(ArgError::Panic("typed rest arguments should be provided as a list of basic values, found a flag".to_owned())),
},

_ => Err(ArgError::Panic(format!("rest arguments should be provided as a list of command arguments, got: {value:?}"))),
})
.collect::<Result<Vec<_>, _>>(),

_ => Err(ArgError::Panic(format!(
"rest arguments should be a list, got: {value:?}"
))),
}
fn parse(&self, value: RuntimeValue) -> Result<Self::Parsed, String> {
DetachedListType::<T>::parse(value)
}

type TypedValueParser = DetachedListType<T>;
Expand Down
7 changes: 1 addition & 6 deletions crates/builtins/src/helpers/fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,7 @@ macro_rules! define_internal_fn {
|arg| arg.arg_value_at
);

arg_handler.parse(<$arg_handler_type as ArgHandler>::min_unwrap(arg.map(|arg| arg.value))).map_err(|err| {
match err {
ArgError::TypeError(error) => (arg_at, error),
ArgError::Panic(error) => ctx.panic(arg_at, error)
}
})?
arg_handler.parse(<$arg_handler_type as ArgHandler>::min_unwrap(arg.map(|arg| arg.value))).map_err(|err| (arg_at, err))?
} ),*
};

Expand Down

0 comments on commit 3901470

Please sign in to comment.