Rename Arguments to Args

This commit is contained in:
Laurenz 2021-09-10 12:27:33 +02:00
parent d2618acd8d
commit f592662aa0
8 changed files with 60 additions and 64 deletions

View File

@ -16,13 +16,13 @@ struct Inner<T: ?Sized> {
func: T, func: T,
} }
type Func = dyn Fn(&mut EvalContext, &mut Arguments) -> TypResult<Value>; type Func = dyn Fn(&mut EvalContext, &mut Args) -> TypResult<Value>;
impl Function { impl Function {
/// Create a new function from a rust closure. /// Create a new function from a rust closure.
pub fn new<F>(name: Option<EcoString>, func: F) -> Self pub fn new<F>(name: Option<EcoString>, func: F) -> Self
where where
F: Fn(&mut EvalContext, &mut Arguments) -> TypResult<Value> + 'static, F: Fn(&mut EvalContext, &mut Args) -> TypResult<Value> + 'static,
{ {
Self(Rc::new(Inner { name, func })) Self(Rc::new(Inner { name, func }))
} }
@ -33,7 +33,7 @@ impl Function {
} }
/// Call the function in the context with the arguments. /// Call the function in the context with the arguments.
pub fn call(&self, ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn call(&self, ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
(&self.0.func)(ctx, args) (&self.0.func)(ctx, args)
} }
} }
@ -58,16 +58,16 @@ impl PartialEq for Function {
/// Evaluated arguments to a function. /// Evaluated arguments to a function.
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct Arguments { pub struct Args {
/// The span of the whole argument list. /// The span of the whole argument list.
pub span: Span, pub span: Span,
/// The positional and named arguments. /// The positional and named arguments.
pub items: Vec<Argument>, pub items: Vec<Arg>,
} }
/// An argument to a function call: `12` or `draw: false`. /// An argument to a function call: `12` or `draw: false`.
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq)]
pub struct Argument { pub struct Arg {
/// The span of the whole argument. /// The span of the whole argument.
pub span: Span, pub span: Span,
/// The name of the argument (`None` for positional arguments). /// The name of the argument (`None` for positional arguments).
@ -76,7 +76,7 @@ pub struct Argument {
pub value: Spanned<Value>, pub value: Spanned<Value>,
} }
impl Arguments { impl Args {
/// Find and consume the first castable positional argument. /// Find and consume the first castable positional argument.
pub fn eat<T>(&mut self) -> Option<T> pub fn eat<T>(&mut self) -> Option<T>
where where
@ -169,11 +169,11 @@ impl Arguments {
{ {
let mut iter = self.items.into_iter(); let mut iter = self.items.into_iter();
let value = match iter.next() { let value = match iter.next() {
Some(Argument { name: None, value, .. }) => value.v.cast().at(value.span)?, Some(Arg { name: None, value, .. }) => value.v.cast().at(value.span)?,
None => { None => {
bail!(self.span, "missing {}", what); bail!(self.span, "missing {}", what);
} }
Some(Argument { name: Some(_), span, .. }) => { Some(Arg { name: Some(_), span, .. }) => {
bail!(span, "named pair is not allowed here"); bail!(span, "named pair is not allowed here");
} }
}; };
@ -186,7 +186,7 @@ impl Arguments {
} }
} }
impl Debug for Arguments { impl Debug for Args {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_char('(')?; f.write_char('(')?;
for (i, arg) in self.items.iter().enumerate() { for (i, arg) in self.items.iter().enumerate() {
@ -199,7 +199,7 @@ impl Debug for Arguments {
} }
} }
impl Debug for Argument { impl Debug for Arg {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(name) = &self.name { if let Some(name) = &self.name {
f.write_str(name)?; f.write_str(name)?;
@ -210,5 +210,5 @@ impl Debug for Argument {
} }
dynamic! { dynamic! {
Arguments: "arguments", Args: "arguments",
} }

View File

@ -393,7 +393,7 @@ impl Eval for CallExpr {
} }
impl Eval for CallArgs { impl Eval for CallArgs {
type Output = Arguments; type Output = Args;
fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> { fn eval(&self, ctx: &mut EvalContext) -> TypResult<Self::Output> {
let mut items = Vec::with_capacity(self.items.len()); let mut items = Vec::with_capacity(self.items.len());
@ -402,14 +402,14 @@ impl Eval for CallArgs {
let span = arg.span(); let span = arg.span();
match arg { match arg {
CallArg::Pos(expr) => { CallArg::Pos(expr) => {
items.push(Argument { items.push(Arg {
span, span,
name: None, name: None,
value: Spanned::new(expr.eval(ctx)?, expr.span()), value: Spanned::new(expr.eval(ctx)?, expr.span()),
}); });
} }
CallArg::Named(Named { name, expr }) => { CallArg::Named(Named { name, expr }) => {
items.push(Argument { items.push(Arg {
span, span,
name: Some((&name.string).into()), name: Some((&name.string).into()),
value: Spanned::new(expr.eval(ctx)?, expr.span()), value: Spanned::new(expr.eval(ctx)?, expr.span()),
@ -417,14 +417,14 @@ impl Eval for CallArgs {
} }
CallArg::Spread(expr) => match expr.eval(ctx)? { CallArg::Spread(expr) => match expr.eval(ctx)? {
Value::Array(array) => { Value::Array(array) => {
items.extend(array.into_iter().map(|value| Argument { items.extend(array.into_iter().map(|value| Arg {
span, span,
name: None, name: None,
value: Spanned::new(value, span), value: Spanned::new(value, span),
})); }));
} }
Value::Dict(dict) => { Value::Dict(dict) => {
items.extend(dict.into_iter().map(|(key, value)| Argument { items.extend(dict.into_iter().map(|(key, value)| Arg {
span, span,
name: Some(key), name: Some(key),
value: Spanned::new(value, span), value: Spanned::new(value, span),
@ -432,7 +432,7 @@ impl Eval for CallArgs {
} }
v => { v => {
if let Value::Dyn(dynamic) = &v { if let Value::Dyn(dynamic) = &v {
if let Some(args) = dynamic.downcast_ref::<Arguments>() { if let Some(args) = dynamic.downcast_ref::<Args>() {
items.extend(args.items.iter().cloned()); items.extend(args.items.iter().cloned());
continue; continue;
} }
@ -444,7 +444,7 @@ impl Eval for CallArgs {
} }
} }
Ok(Arguments { span: self.span, items }) Ok(Args { span: self.span, items })
} }
} }

View File

@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter};
use std::iter; use std::iter;
use std::rc::Rc; use std::rc::Rc;
use super::{Arguments, EvalContext, Function, Value}; use super::{Args, EvalContext, Function, Value};
use crate::diag::TypResult; use crate::diag::TypResult;
use crate::util::EcoString; use crate::util::EcoString;
@ -91,7 +91,7 @@ impl Scope {
/// Define a constant function. /// Define a constant function.
pub fn def_func<F>(&mut self, name: impl Into<EcoString>, f: F) pub fn def_func<F>(&mut self, name: impl Into<EcoString>, f: F)
where where
F: Fn(&mut EvalContext, &mut Arguments) -> TypResult<Value> + 'static, F: Fn(&mut EvalContext, &mut Args) -> TypResult<Value> + 'static,
{ {
let name = name.into(); let name = name.into();
self.def_const(name.clone(), Function::new(Some(name), f)); self.def_const(name.clone(), Function::new(Some(name), f));

View File

@ -10,7 +10,7 @@ use crate::layout::{
}; };
/// `image`: An image. /// `image`: An image.
pub fn image(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn image(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let path = args.expect::<Spanned<Str>>("path to image file")?; let path = args.expect::<Spanned<Str>>("path to image file")?;
let width = args.named("width")?; let width = args.named("width")?;
let height = args.named("height")?; let height = args.named("height")?;
@ -31,7 +31,7 @@ pub fn image(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `rect`: A rectangle with optional content. /// `rect`: A rectangle with optional content.
pub fn rect(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn rect(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?; let width = args.named("width")?;
let height = args.named("height")?; let height = args.named("height")?;
let fill = args.named("fill")?; let fill = args.named("fill")?;
@ -40,7 +40,7 @@ pub fn rect(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `square`: A square with optional content. /// `square`: A square with optional content.
pub fn square(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn square(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let length = args.named::<Length>("length")?.map(Linear::from); let length = args.named::<Length>("length")?.map(Linear::from);
let width = match length { let width = match length {
Some(length) => Some(length), Some(length) => Some(length),
@ -84,7 +84,7 @@ fn rect_impl(
} }
/// `ellipse`: An ellipse with optional content. /// `ellipse`: An ellipse with optional content.
pub fn ellipse(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn ellipse(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?; let width = args.named("width")?;
let height = args.named("height")?; let height = args.named("height")?;
let fill = args.named("fill")?; let fill = args.named("fill")?;
@ -93,7 +93,7 @@ pub fn ellipse(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `circle`: A circle with optional content. /// `circle`: A circle with optional content.
pub fn circle(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn circle(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let diameter = args.named("radius")?.map(|r: Length| 2.0 * Linear::from(r)); let diameter = args.named("radius")?.map(|r: Length| 2.0 * Linear::from(r));
let width = match diameter { let width = match diameter {
None => args.named("width")?, None => args.named("width")?,

View File

@ -3,7 +3,7 @@ use crate::layout::{FixedNode, GridNode, PadNode, StackChild, StackNode, TrackSi
use crate::paper::{Paper, PaperClass}; use crate::paper::{Paper, PaperClass};
/// `page`: Configure pages. /// `page`: Configure pages.
pub fn page(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let paper = match args.eat::<Spanned<Str>>() { let paper = match args.eat::<Spanned<Str>>() {
Some(name) => match Paper::from_name(&name.v) { Some(name) => match Paper::from_name(&name.v) {
None => bail!(name.span, "invalid paper name"), None => bail!(name.span, "invalid paper name"),
@ -70,27 +70,27 @@ pub fn page(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `pagebreak`: Start a new page. /// `pagebreak`: Start a new page.
pub fn pagebreak(ctx: &mut EvalContext, _: &mut Arguments) -> TypResult<Value> { pub fn pagebreak(ctx: &mut EvalContext, _: &mut Args) -> TypResult<Value> {
ctx.template.pagebreak(true); ctx.template.pagebreak(true);
Ok(Value::None) Ok(Value::None)
} }
/// `h`: Horizontal spacing. /// `h`: Horizontal spacing.
pub fn h(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn h(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let spacing = args.expect("spacing")?; let spacing = args.expect("spacing")?;
ctx.template.spacing(GenAxis::Inline, spacing); ctx.template.spacing(GenAxis::Inline, spacing);
Ok(Value::None) Ok(Value::None)
} }
/// `v`: Vertical spacing. /// `v`: Vertical spacing.
pub fn v(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn v(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let spacing = args.expect("spacing")?; let spacing = args.expect("spacing")?;
ctx.template.spacing(GenAxis::Block, spacing); ctx.template.spacing(GenAxis::Block, spacing);
Ok(Value::None) Ok(Value::None)
} }
/// `align`: Configure the alignment along the layouting axes. /// `align`: Configure the alignment along the layouting axes.
pub fn align(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn align(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let first = args.eat::<Align>(); let first = args.eat::<Align>();
let second = args.eat::<Align>(); let second = args.eat::<Align>();
let body = args.eat::<Template>(); let body = args.eat::<Template>();
@ -140,7 +140,7 @@ pub fn align(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `box`: Place content in a rectangular box. /// `box`: Place content in a rectangular box.
pub fn boxed(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn boxed(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?; let width = args.named("width")?;
let height = args.named("height")?; let height = args.named("height")?;
let body: Template = args.eat().unwrap_or_default(); let body: Template = args.eat().unwrap_or_default();
@ -155,7 +155,7 @@ pub fn boxed(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `block`: Place content in a block. /// `block`: Place content in a block.
pub fn block(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn block(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let body: Template = args.expect("body")?; let body: Template = args.expect("body")?;
Ok(Value::Template(Template::from_block(move |state| { Ok(Value::Template(Template::from_block(move |state| {
body.to_stack(state) body.to_stack(state)
@ -163,7 +163,7 @@ pub fn block(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `pad`: Pad content at the sides. /// `pad`: Pad content at the sides.
pub fn pad(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn pad(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let all = args.eat(); let all = args.eat();
let left = args.named("left")?; let left = args.named("left")?;
let top = args.named("top")?; let top = args.named("top")?;
@ -187,7 +187,7 @@ pub fn pad(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `stack`: Stack children along an axis. /// `stack`: Stack children along an axis.
pub fn stack(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let dir = args.named("dir")?; let dir = args.named("dir")?;
let children: Vec<Template> = args.all().collect(); let children: Vec<Template> = args.all().collect();
@ -210,7 +210,7 @@ pub fn stack(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `grid`: Arrange children into a grid. /// `grid`: Arrange children into a grid.
pub fn grid(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let columns = args.named("columns")?.unwrap_or_default(); let columns = args.named("columns")?.unwrap_or_default();
let rows = args.named("rows")?.unwrap_or_default(); let rows = args.named("rows")?.unwrap_or_default();

View File

@ -18,7 +18,7 @@ use std::rc::Rc;
use crate::color::{Color, RgbaColor}; use crate::color::{Color, RgbaColor};
use crate::diag::{At, TypResult}; use crate::diag::{At, TypResult};
use crate::eval::{Arguments, Array, EvalContext, Scope, State, Str, Template, Value}; use crate::eval::{Args, Array, EvalContext, Scope, State, Str, Template, Value};
use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric};
use crate::geom::*; use crate::geom::*;
use crate::layout::LayoutNode; use crate::layout::LayoutNode;

View File

@ -3,7 +3,7 @@ use crate::layout::{Decoration, LineDecoration, LineKind, Paint};
use super::*; use super::*;
/// `font`: Configure the font. /// `font`: Configure the font.
pub fn font(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let list = args.named("family")?.or_else(|| { let list = args.named("family")?.or_else(|| {
let families: Vec<_> = args.all().collect(); let families: Vec<_> = args.all().collect();
(!families.is_empty()).then(|| FontDef(Rc::new(families))) (!families.is_empty()).then(|| FontDef(Rc::new(families)))
@ -111,7 +111,7 @@ castable! {
} }
/// `par`: Configure paragraphs. /// `par`: Configure paragraphs.
pub fn par(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn par(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let par_spacing = args.named("spacing")?; let par_spacing = args.named("spacing")?;
let line_spacing = args.named("leading")?; let line_spacing = args.named("leading")?;
@ -133,7 +133,7 @@ pub fn par(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `lang`: Configure the language. /// `lang`: Configure the language.
pub fn lang(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn lang(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let iso = args.eat::<Str>(); let iso = args.eat::<Str>();
let dir = if let Some(dir) = args.named::<Spanned<Dir>>("dir")? { let dir = if let Some(dir) = args.named::<Spanned<Dir>>("dir")? {
if dir.v.axis() == SpecAxis::Horizontal { if dir.v.axis() == SpecAxis::Horizontal {
@ -164,25 +164,21 @@ fn lang_dir(iso: &str) -> Dir {
} }
/// `strike`: Set striken-through text. /// `strike`: Set striken-through text.
pub fn strike(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn strike(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
line_impl(ctx, args, LineKind::Strikethrough) line_impl(ctx, args, LineKind::Strikethrough)
} }
/// `underline`: Set underlined text. /// `underline`: Set underlined text.
pub fn underline(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn underline(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
line_impl(ctx, args, LineKind::Underline) line_impl(ctx, args, LineKind::Underline)
} }
/// `overline`: Set text with an overline. /// `overline`: Set text with an overline.
pub fn overline(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn overline(ctx: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
line_impl(ctx, args, LineKind::Overline) line_impl(ctx, args, LineKind::Overline)
} }
fn line_impl( fn line_impl(_: &mut EvalContext, args: &mut Args, kind: LineKind) -> TypResult<Value> {
_: &mut EvalContext,
args: &mut Arguments,
kind: LineKind,
) -> TypResult<Value> {
let stroke = args.named("stroke")?.or_else(|| args.eat()); let stroke = args.named("stroke")?.or_else(|| args.eat());
let thickness = args.named::<Linear>("thickness")?.or_else(|| args.eat()); let thickness = args.named::<Linear>("thickness")?.or_else(|| args.eat());
let offset = args.named("offset")?; let offset = args.named("offset")?;
@ -201,7 +197,7 @@ fn line_impl(
} }
/// `link`: Set a link. /// `link`: Set a link.
pub fn link(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn link(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let url = args.expect::<Str>("url")?; let url = args.expect::<Str>("url")?;
let mut body = args.eat().unwrap_or_else(|| { let mut body = args.eat().unwrap_or_else(|| {

View File

@ -6,18 +6,18 @@ use crate::color::{Color, RgbaColor};
use super::*; use super::*;
/// `type`: The name of a value's type. /// `type`: The name of a value's type.
pub fn type_(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn type_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(args.expect::<Value>("value")?.type_name().into()) Ok(args.expect::<Value>("value")?.type_name().into())
} }
/// `repr`: The string representation of a value. /// `repr`: The string representation of a value.
pub fn repr(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn repr(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(args.expect::<Value>("value")?.repr().into()) Ok(args.expect::<Value>("value")?.repr().into())
} }
/// `join`: Join a sequence of values, optionally interspersing it with another /// `join`: Join a sequence of values, optionally interspersing it with another
/// value. /// value.
pub fn join(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn join(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let span = args.span; let span = args.span;
let sep = args.named::<Value>("sep")?.unwrap_or(Value::None); let sep = args.named::<Value>("sep")?.unwrap_or(Value::None);
@ -37,7 +37,7 @@ pub fn join(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `int`: Try to convert a value to a integer. /// `int`: Try to convert a value to a integer.
pub fn int(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn int(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("value")?; let Spanned { v, span } = args.expect("value")?;
Ok(Value::Int(match v { Ok(Value::Int(match v {
Value::Bool(v) => v as i64, Value::Bool(v) => v as i64,
@ -52,7 +52,7 @@ pub fn int(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `float`: Try to convert a value to a float. /// `float`: Try to convert a value to a float.
pub fn float(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn float(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("value")?; let Spanned { v, span } = args.expect("value")?;
Ok(Value::Float(match v { Ok(Value::Float(match v {
Value::Int(v) => v as f64, Value::Int(v) => v as f64,
@ -66,7 +66,7 @@ pub fn float(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `str`: Try to convert a value to a string. /// `str`: Try to convert a value to a string.
pub fn str(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn str(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("value")?; let Spanned { v, span } = args.expect("value")?;
Ok(Value::Str(match v { Ok(Value::Str(match v {
Value::Int(v) => format_str!("{}", v), Value::Int(v) => format_str!("{}", v),
@ -77,7 +77,7 @@ pub fn str(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `abs`: The absolute value of a numeric value. /// `abs`: The absolute value of a numeric value.
pub fn abs(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn abs(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("numeric value")?; let Spanned { v, span } = args.expect("numeric value")?;
Ok(match v { Ok(match v {
Value::Int(v) => Value::Int(v.abs()), Value::Int(v) => Value::Int(v.abs()),
@ -92,17 +92,17 @@ pub fn abs(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `min`: The minimum of a sequence of values. /// `min`: The minimum of a sequence of values.
pub fn min(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn min(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
minmax(args, Ordering::Less) minmax(args, Ordering::Less)
} }
/// `max`: The maximum of a sequence of values. /// `max`: The maximum of a sequence of values.
pub fn max(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn max(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
minmax(args, Ordering::Greater) minmax(args, Ordering::Greater)
} }
/// Find the minimum or maximum of a sequence of values. /// Find the minimum or maximum of a sequence of values.
fn minmax(args: &mut Arguments, goal: Ordering) -> TypResult<Value> { fn minmax(args: &mut Args, goal: Ordering) -> TypResult<Value> {
let mut extremum = args.expect::<Value>("value")?; let mut extremum = args.expect::<Value>("value")?;
for Spanned { v, span } in args.all::<Spanned<Value>>() { for Spanned { v, span } in args.all::<Spanned<Value>>() {
match v.partial_cmp(&extremum) { match v.partial_cmp(&extremum) {
@ -123,7 +123,7 @@ fn minmax(args: &mut Arguments, goal: Ordering) -> TypResult<Value> {
} }
/// `rgb`: Create an RGB(A) color. /// `rgb`: Create an RGB(A) color.
pub fn rgb(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn rgb(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(Value::Color(Color::Rgba( Ok(Value::Color(Color::Rgba(
if let Some(string) = args.eat::<Spanned<Str>>() { if let Some(string) = args.eat::<Spanned<Str>>() {
match RgbaColor::from_str(&string.v) { match RgbaColor::from_str(&string.v) {
@ -142,17 +142,17 @@ pub fn rgb(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `lower`: Convert a string to lowercase. /// `lower`: Convert a string to lowercase.
pub fn lower(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn lower(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(args.expect::<Str>("string")?.to_lowercase().into()) Ok(args.expect::<Str>("string")?.to_lowercase().into())
} }
/// `upper`: Convert a string to uppercase. /// `upper`: Convert a string to uppercase.
pub fn upper(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn upper(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
Ok(args.expect::<Str>("string")?.to_uppercase().into()) Ok(args.expect::<Str>("string")?.to_uppercase().into())
} }
/// `len`: The length of a string, an array or a dictionary. /// `len`: The length of a string, an array or a dictionary.
pub fn len(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn len(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect("collection")?; let Spanned { v, span } = args.expect("collection")?;
Ok(Value::Int(match v { Ok(Value::Int(match v {
Value::Str(v) => v.len(), Value::Str(v) => v.len(),
@ -163,7 +163,7 @@ pub fn len(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
} }
/// `sorted`: The sorted version of an array. /// `sorted`: The sorted version of an array.
pub fn sorted(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> { pub fn sorted(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let Spanned { v, span } = args.expect::<Spanned<Array>>("array")?; let Spanned { v, span } = args.expect::<Spanned<Array>>("array")?;
Ok(Value::Array(v.sorted().at(span)?)) Ok(Value::Array(v.sorted().at(span)?))
} }