diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-12-13 14:58:14 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-12-13 14:58:14 +0100 |
| commit | 971ff3a2dcff1e68bf7e19017113469aad5a30c2 (patch) | |
| tree | f6776688446f278882947f713401b9a92b8e9384 | |
| parent | f549914ff8d66e48e779d4d99898a224bd1ab701 (diff) | |
Implement expression kind for Spanned<T> 👩💻
| -rw-r--r-- | src/library/align.rs | 4 | ||||
| -rw-r--r-- | src/library/boxed.rs | 4 | ||||
| -rw-r--r-- | src/library/direction.rs | 4 | ||||
| -rw-r--r-- | src/library/maps.rs | 9 | ||||
| -rw-r--r-- | src/library/mod.rs | 38 | ||||
| -rw-r--r-- | src/syntax/mod.rs | 27 |
6 files changed, 43 insertions, 43 deletions
diff --git a/src/library/align.rs b/src/library/align.rs index 616ede6b..e6952dc2 100644 --- a/src/library/align.rs +++ b/src/library/align.rs @@ -13,8 +13,8 @@ function! { parse(args, body, ctx) { let mut map = ConsistentMap::new(); - map.add_opt_span(Key::First, args.get_pos_opt::<AlignmentKey>()?)?; - map.add_opt_span(Key::Second, args.get_pos_opt::<AlignmentKey>()?)?; + map.add_opt(Key::First, args.get_pos_opt::<AlignmentKey>()?)?; + map.add_opt(Key::Second, args.get_pos_opt::<AlignmentKey>()?)?; for arg in args.keys() { let axis = AxisKey::from_ident(&arg.v.key)?; diff --git a/src/library/boxed.rs b/src/library/boxed.rs index c205eec6..2d0d6e6b 100644 --- a/src/library/boxed.rs +++ b/src/library/boxed.rs @@ -14,9 +14,7 @@ function! { Boxed { body: parse!(optional: body, ctx).unwrap_or(SyntaxTree::new()), map: ExtentMap::new(&mut args, false)?, - debug: args.get_key_opt::<bool>("debug")? - .map(Spanned::value) - .unwrap_or(true), + debug: args.get_key_opt::<bool>("debug")?.unwrap_or(true), } } diff --git a/src/library/direction.rs b/src/library/direction.rs index ac1fac08..59c0d1fd 100644 --- a/src/library/direction.rs +++ b/src/library/direction.rs @@ -13,8 +13,8 @@ function! { parse(args, body, ctx) { let mut map = ConsistentMap::new(); - map.add_opt_span(AxisKey::Primary, args.get_pos_opt::<Direction>()?)?; - map.add_opt_span(AxisKey::Secondary, args.get_pos_opt::<Direction>()?)?; + map.add_opt(AxisKey::Primary, args.get_pos_opt::<Direction>()?)?; + map.add_opt(AxisKey::Secondary, args.get_pos_opt::<Direction>()?)?; for arg in args.keys() { let axis = AxisKey::from_ident(&arg.v.key)?; diff --git a/src/library/maps.rs b/src/library/maps.rs index 4eafd9cc..13b4dc5d 100644 --- a/src/library/maps.rs +++ b/src/library/maps.rs @@ -31,13 +31,6 @@ impl<K, V> ConsistentMap<K, V> where K: Hash + Eq { }) } - /// Add a key-spanned-value pair the value is not `None`. - pub fn add_opt_span(&mut self, key: K, value: Option<Spanned<V>>) -> ParseResult<()> { - Ok(if let Some(spanned) = value { - self.add(key, spanned.v)?; - }) - } - /// Call a function with the value if the key is present. pub fn with<F>(&self, key: K, callback: F) where F: FnOnce(&V) { if let Some(value) = self.map.get(&key) { @@ -143,7 +136,7 @@ impl PaddingMap { pub fn new(args: &mut FuncArgs, enforce: bool) -> ParseResult<PaddingMap> { let mut map = ConsistentMap::new(); - map.add_opt_span(PaddingKey::All, args.get_pos_opt::<Size>()?)?; + map.add_opt(PaddingKey::All, args.get_pos_opt::<Size>()?)?; for arg in args.keys() { let key = match PaddingKey::from_ident(&arg.v.key) { diff --git a/src/library/mod.rs b/src/library/mod.rs index 0fcc8647..9a49896b 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -133,7 +133,7 @@ function! { let spacing = if let Some(axis) = meta { Spacing { axis, - spacing: FSize::from_expr(args.get_pos::<Expression>()?)?, + spacing: FSize::from_expr(args.get_pos::<Spanned<Expression>>()?)?, } } else { if let Some(arg) = args.get_key_next() { @@ -178,15 +178,7 @@ function! { layout(self, ctx) { let mut style = ctx.style.text.clone(); style.toggle_class(self.class.clone()); - - match &self.body { - Some(body) => vec![ - SetTextStyle(style), - LayoutTree(body), - SetTextStyle(ctx.style.text.clone()), - ], - None => vec![SetTextStyle(style)] - } + styled(&self.body, &ctx, style) } } @@ -201,21 +193,29 @@ function! { parse(args, body, ctx) { FontSize { body: parse!(optional: body, ctx), - size: args.get_pos::<Size>()?.v, + size: args.get_pos::<Size>()?, } } layout(self, ctx) { let mut style = ctx.style.text.clone(); style.font_size = self.size; + styled(&self.body, &ctx, style) + } +} - match &self.body { - Some(body) => vec![ - SetTextStyle(style), - LayoutTree(body), - SetTextStyle(ctx.style.text.clone()), - ], - None => vec![SetTextStyle(style)] - } +/// Layout the body with the style or update the style if there is no body. +fn styled<'a>( + body: &'a Option<SyntaxTree>, + ctx: &LayoutContext, + style: TextStyle +) -> Commands<'a> { + match &body { + Some(body) => vec![ + SetTextStyle(style), + LayoutTree(body), + SetTextStyle(ctx.style.text.clone()), + ], + None => vec![SetTextStyle(style)] } } diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index 2f64bc9b..57488121 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -121,16 +121,15 @@ impl FuncArgs { } /// Force-extract the first positional argument. - pub fn get_pos<E: ExpressionKind>(&mut self) -> ParseResult<Spanned<E>> { + pub fn get_pos<E: ExpressionKind>(&mut self) -> ParseResult<E> { expect(self.get_pos_opt()) } /// Extract the first positional argument. - pub fn get_pos_opt<E: ExpressionKind>(&mut self) -> ParseResult<Option<Spanned<E>>> { + pub fn get_pos_opt<E: ExpressionKind>(&mut self) -> ParseResult<Option<E>> { Ok(if !self.pos.is_empty() { let spanned = self.pos.remove(0); - let span = spanned.span; - Some(Spanned::new(E::from_expr(spanned)?, span)) + Some(E::from_expr(spanned)?) } else { None }) @@ -143,15 +142,15 @@ impl FuncArgs { } /// Force-extract a keyword argument. - pub fn get_key<E: ExpressionKind>(&mut self, name: &str) -> ParseResult<Spanned<E>> { + pub fn get_key<E: ExpressionKind>(&mut self, name: &str) -> ParseResult<E> { expect(self.get_key_opt(name)) } /// Extract a keyword argument. - pub fn get_key_opt<E: ExpressionKind>(&mut self, name: &str) -> ParseResult<Option<Spanned<E>>> { + pub fn get_key_opt<E: ExpressionKind>(&mut self, name: &str) -> ParseResult<Option<E>> { Ok(if let Some(index) = self.key.iter().position(|arg| arg.v.key.v.0 == name) { - let Spanned { v, span } = self.key.swap_remove(index); - Some(Spanned::new(E::from_expr(v.value)?, span)) + let value = self.key.swap_remove(index).v.value; + Some(E::from_expr(value)?) } else { None }) @@ -181,7 +180,7 @@ impl FuncArgs { } /// Extract the option expression kind from the option or return an error. -fn expect<E: ExpressionKind>(opt: ParseResult<Option<Spanned<E>>>) -> ParseResult<Spanned<E>> { +fn expect<E: ExpressionKind>(opt: ParseResult<Option<E>>) -> ParseResult<E> { match opt { Ok(Some(spanned)) => Ok(spanned), Ok(None) => error!("expected {}", E::NAME), @@ -308,3 +307,13 @@ kind!(ScaleSize, "number or size", Expression::Size(size) => ScaleSize::Absolute(size), Expression::Num(scale) => ScaleSize::Scaled(scale as f32) ); + +impl<T> ExpressionKind for Spanned<T> where T: ExpressionKind { + const NAME: &'static str = T::NAME; + + fn from_expr(expr: Spanned<Expression>) -> ParseResult<Spanned<T>> { + let span = expr.span; + T::from_expr(expr) + .map(|v| Spanned::new(v, span)) + } +} |
