From 335fa2d118718b4dba539294a8ef6c96c5bbf09e Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 4 Oct 2020 23:31:35 +0200 Subject: =?UTF-8?q?Small=20improvements=20=F0=9F=8D=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/eval/args.rs | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'src/eval/args.rs') 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 + where + K: Into>, + 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(&mut self) -> Option where @@ -104,6 +136,7 @@ impl Args { #[cfg(test)] mod tests { + use super::super::{Dict, SpannedEntry, Value}; use super::*; fn entry(value: Value) -> SpannedEntry { -- cgit v1.2.3