Always use first positional argument in expect()

This changes `#h(100)` from "missing argument: spacing" to "expected linear, found integer".
This commit is contained in:
Laurenz 2021-10-05 19:45:38 +02:00
parent 0a23bfbc23
commit ae05dc0876
4 changed files with 15 additions and 12 deletions

View File

@ -93,16 +93,21 @@ impl Args {
None
}
/// Find and consume the first castable positional argument, returning a
/// `missing argument: {what}` error if no match was found.
/// Try to cast the first positional argument ir returning a `missing
/// argument: {what}` error if no positional argument is left.
pub fn expect<T>(&mut self, what: &str) -> TypResult<T>
where
T: Cast<Spanned<Value>>,
{
match self.eat() {
Some(found) => Ok(found),
None => bail!(self.span, "missing argument: {}", what),
for (i, slot) in self.items.iter().enumerate() {
if slot.name.is_none() {
let value = self.items.remove(i).value;
let span = value.span;
return T::cast(value).at(span);
}
}
bail!(self.span, "missing argument: {}", what);
}
/// Find and consume all castable positional arguments.

View File

@ -6,11 +6,9 @@ use crate::color::{Color, RgbaColor};
/// `assert`: Ensure that a condition is fulfilled.
pub fn assert(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("condition")?;
match v {
Value::Bool(true) => {}
Value::Bool(false) => bail!(span, "assertion failed"),
v => bail!(span, "expected boolean, found {}", v.type_name()),
let Spanned { v, span } = args.expect::<Spanned<bool>>("condition")?;
if !v {
bail!(span, "assertion failed");
}
Ok(Value::None)
}

View File

@ -19,7 +19,7 @@
#len()
---
// Error: 6-10 expected string, array or dictionary
// Error: 6-10 expected string, array or dictionary, found length
#len(12pt)
---

View File

@ -16,7 +16,7 @@
#abs(10pt + 50%)
---
// Error: 6-17 expected numeric value
// Error: 6-17 expected numeric value, found string
#abs("no number")
---