diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-10-04 23:31:35 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-10-04 23:31:35 +0200 |
| commit | 335fa2d118718b4dba539294a8ef6c96c5bbf09e (patch) | |
| tree | 08e48d0c18c350bc9479d0d801d2320628d8e4a2 /src/eval/args.rs | |
| parent | 605ab104c5e041c345007020d277b4c6267debe6 (diff) | |
Small improvements 🍪
Diffstat (limited to 'src/eval/args.rs')
| -rw-r--r-- | src/eval/args.rs | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/src/eval/args.rs b/src/eval/args.rs index d71cc374..b89ee61f 100644 --- a/src/eval/args.rs +++ b/src/eval/args.rs @@ -2,7 +2,9 @@ use std::mem; -use super::*; +use super::{Convert, RefKey, ValueDict}; +use crate::layout::LayoutContext; +use crate::syntax::{SpanWith, Spanned}; /// A wrapper around a dictionary value that simplifies argument parsing in /// functions. @@ -21,14 +23,44 @@ impl Args { { self.0.v.remove(key).and_then(|entry| { let span = entry.value.span; - let (t, diag) = T::convert(entry.value); + let (result, diag) = T::convert(entry.value); if let Some(diag) = diag { ctx.f.diags.push(diag.span_with(span)) } - t.ok() + result.ok() }) } + /// This is the same as [`get`], except that it generates an error about a + /// missing argument with the given `name` if the key does not exist. + /// + /// [`get`]: #method.get + pub fn need<'a, K, T>( + &mut self, + ctx: &mut LayoutContext, + key: K, + name: &str, + ) -> Option<T> + where + K: Into<RefKey<'a>>, + T: Convert, + { + match self.0.v.remove(key) { + Some(entry) => { + let span = entry.value.span; + let (result, diag) = T::convert(entry.value); + if let Some(diag) = diag { + ctx.f.diags.push(diag.span_with(span)) + } + result.ok() + } + None => { + ctx.f.diags.push(error!(self.0.span, "missing argument: {}", name)); + None + } + } + } + /// Retrieve and remove the first matching positional argument. pub fn find<T>(&mut self) -> Option<T> where @@ -104,6 +136,7 @@ impl Args { #[cfg(test)] mod tests { + use super::super::{Dict, SpannedEntry, Value}; use super::*; fn entry(value: Value) -> SpannedEntry<Value> { |
