diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-08-02 11:06:45 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-08-02 11:06:45 +0200 |
| commit | efb78831a7a9fe8c807c326a1bfa338b50579938 (patch) | |
| tree | 7bbba4130ac47809c72efeac796b2ca71b72e659 /src/syntax | |
| parent | 659248d52ff9e6be4dad7c4555bd62899671ad55 (diff) | |
Unify font and page functions 💕
- Removes font weight and width warnings for now, will be added again later
- Adds a bit hacky get_first function for tuples, will be refactored soon anyway
Diffstat (limited to 'src/syntax')
| -rw-r--r-- | src/syntax/expr.rs | 19 | ||||
| -rw-r--r-- | src/syntax/func/maps.rs | 2 | ||||
| -rw-r--r-- | src/syntax/func/mod.rs | 13 | ||||
| -rw-r--r-- | src/syntax/func/values.rs | 14 |
4 files changed, 37 insertions, 11 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index d849366c..51daf304 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -268,6 +268,25 @@ impl Tuple { None } + /// Extract (and remove) the first matching value without removing and + /// generating diagnostics for all previous items that did not match. + pub fn get_first<V: Value>(&mut self, _: &mut Diagnostics) -> Option<V> { + let mut i = 0; + while i < self.items.len() { + let expr = self.items[i].clone(); + match V::parse(expr) { + Ok(output) => { + self.items.remove(i); + return Some(output) + } + Err(_) => {}, + } + i += 1; + } + + None + } + /// Extract and return an iterator over all values that match and generate /// diagnostics for all items that do not match. pub fn get_all<'a, V: Value>(&'a mut self, diagnostics: &'a mut Diagnostics) diff --git a/src/syntax/func/maps.rs b/src/syntax/func/maps.rs index 59159ae1..bc290a9e 100644 --- a/src/syntax/func/maps.rs +++ b/src/syntax/func/maps.rs @@ -178,7 +178,7 @@ impl PaddingMap { pub fn parse(diagnostics: &mut Diagnostics, args: &mut FuncArgs) -> PaddingMap { let mut map = DedupMap::new(); - let all = args.pos.get::<Spanned<Defaultable<ScaleLength>>>(diagnostics); + let all = args.key.get::<Spanned<Defaultable<ScaleLength>>>(diagnostics, "margins"); if let Some(Spanned { v, span }) = all { map.insert(diagnostics, Spanned { v: (PaddingKey::All, v.into()), span }); } diff --git a/src/syntax/func/mod.rs b/src/syntax/func/mod.rs index c2631727..37dccc3d 100644 --- a/src/syntax/func/mod.rs +++ b/src/syntax/func/mod.rs @@ -82,13 +82,22 @@ pub enum FuncArg { } /// Extra methods on [`Options`](Option) used for argument parsing. -pub trait OptionExt: Sized { +pub trait OptionExt<T>: Sized { + /// Calls `f` with `val` if this is `Some(val)`. + fn with(self, f: impl FnOnce(T)); + /// Add an error about a missing argument `arg` with the given span if the /// option is `None`. fn or_missing(self, diagnostics: &mut Diagnostics, span: Span, arg: &str) -> Self; } -impl<T> OptionExt for Option<T> { +impl<T> OptionExt<T> for Option<T> { + fn with(self, f: impl FnOnce(T)) { + if let Some(val) = self { + f(val); + } + } + fn or_missing(self, diagnostics: &mut Diagnostics, span: Span, arg: &str) -> Self { if self.is_none() { diagnostics.push(error!(span, "missing argument: {}", arg)); diff --git a/src/syntax/func/values.rs b/src/syntax/func/values.rs index 64d4d345..d5e9c6e8 100644 --- a/src/syntax/func/values.rs +++ b/src/syntax/func/values.rs @@ -143,22 +143,21 @@ impl Value for FontStyle { /// The additional boolean specifies whether a number was clamped into the range /// 100 - 900 to make it a valid font weight. -impl Value for (FontWeight, bool) { +impl Value for FontWeight { fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> { match expr.v { Expr::Number(weight) => { let weight = weight.round(); if weight >= 100.0 && weight <= 900.0 { - Ok((FontWeight(weight as u16), false)) + Ok(FontWeight(weight as u16)) } else { let clamped = weight.min(900.0).max(100.0); - Ok((FontWeight(clamped as u16), true)) + Ok(FontWeight(clamped as u16)) } } Expr::Ident(id) => { FontWeight::from_name(id.as_str()) .ok_or_else(|| error!("invalid font weight")) - .map(|weight| (weight, false)) } other => Err( error!("expected identifier or number, found {}", other.name()) @@ -169,22 +168,21 @@ impl Value for (FontWeight, bool) { /// The additional boolean specifies whether a number was clamped into the range /// 1 - 9 to make it a valid font width. -impl Value for (FontWidth, bool) { +impl Value for FontWidth { fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> { match expr.v { Expr::Number(width) => { let width = width.round(); if width >= 1.0 && width <= 9.0 { - Ok((FontWidth::new(width as u16).unwrap(), false)) + Ok(FontWidth::new(width as u16).unwrap()) } else { let clamped = width.min(9.0).max(1.0); - Ok((FontWidth::new(clamped as u16).unwrap(), true)) + Ok(FontWidth::new(clamped as u16).unwrap()) } } Expr::Ident(id) => { FontWidth::from_name(id.as_str()) .ok_or_else(|| error!("invalid font width")) - .map(|width| (width, false)) } other => Err( error!("expected identifier or number, found {}", other.name()) |
