diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-08-13 16:39:52 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-08-13 16:55:45 +0200 |
| commit | 6a3385e4e77ce7672bcc80941bf02c8218f344a2 (patch) | |
| tree | 7ae5d668cf7d734f81f1e9d604bbe46fa0775ed8 /src/eval/function.rs | |
| parent | 144f20882136ef81b79d77bd8a68f42b76c66676 (diff) | |
Argument collection and spreading
Diffstat (limited to 'src/eval/function.rs')
| -rw-r--r-- | src/eval/function.rs | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/eval/function.rs b/src/eval/function.rs index d2ec1bb9..550db59d 100644 --- a/src/eval/function.rs +++ b/src/eval/function.rs @@ -60,7 +60,7 @@ impl PartialEq for Function { pub struct FuncArgs { /// The span of the whole argument list. pub span: Span, - /// The positional arguments. + /// The positional and named arguments. pub items: Vec<FuncArg>, } @@ -118,20 +118,28 @@ impl FuncArgs { where T: Cast<Spanned<Value>>, { - let index = match self - .items - .iter() - .filter_map(|arg| arg.name.as_deref()) - .position(|other| name == other) - { - Some(index) => index, - None => return Ok(None), - }; - - let value = self.items.remove(index).value; - let span = value.span; + // We don't quit once we have a match because when multiple matches + // exist, we want to remove all of them and use the last one. + let mut i = 0; + let mut found = None; + while i < self.items.len() { + if self.items[i].name.as_deref() == Some(name) { + let value = self.items.remove(i).value; + let span = value.span; + found = Some(T::cast(value).at(span)?); + } else { + i += 1; + } + } + Ok(found) + } - T::cast(value).map(Some).at(span) + /// Take out all arguments into a new instance. + pub fn take(&mut self) -> Self { + Self { + span: self.span, + items: std::mem::take(&mut self.items), + } } /// Return an "unexpected argument" error if there is any remaining |
