summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-12-13 14:58:14 +0100
committerLaurenz <laurmaedje@gmail.com>2019-12-13 14:58:14 +0100
commit971ff3a2dcff1e68bf7e19017113469aad5a30c2 (patch)
treef6776688446f278882947f713401b9a92b8e9384
parentf549914ff8d66e48e779d4d99898a224bd1ab701 (diff)
Implement expression kind for Spanned<T> 👩‍💻
-rw-r--r--src/library/align.rs4
-rw-r--r--src/library/boxed.rs4
-rw-r--r--src/library/direction.rs4
-rw-r--r--src/library/maps.rs9
-rw-r--r--src/library/mod.rs38
-rw-r--r--src/syntax/mod.rs27
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))
+ }
+}