summaryrefslogtreecommitdiff
path: root/src/library/maps
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-01-13 14:36:40 +0100
committerLaurenz <laurmaedje@gmail.com>2020-01-13 14:36:40 +0100
commitdde69276d47818174c35523c8ed86b6888b6d02b (patch)
tree68f0f56efd42f47156fddf67158cdcdcde3717b9 /src/library/maps
parent6527d31dfba78330a39e52d7772f6c8561fb23ef (diff)
Refactor expressions and create tuples and objects 🧮
Diffstat (limited to 'src/library/maps')
-rw-r--r--src/library/maps/axis.rs27
-rw-r--r--src/library/maps/mod.rs38
-rw-r--r--src/library/maps/padding.rs9
3 files changed, 53 insertions, 21 deletions
diff --git a/src/library/maps/axis.rs b/src/library/maps/axis.rs
index 238d146a..3c3a8c11 100644
--- a/src/library/maps/axis.rs
+++ b/src/library/maps/axis.rs
@@ -34,6 +34,13 @@ key!(AxisKey, "axis",
"secondary" | "s" => Generic(Secondary),
);
+key!(Direction, "direction",
+ "left-to-right" | "ltr" => LeftToRight,
+ "right-to-left" | "rtl" => RightToLeft,
+ "top-to-bottom" | "ttb" => TopToBottom,
+ "bottom-to-top" | "btt" => BottomToTop,
+);
+
/// A map for storing extents along axes.
#[derive(Debug, Clone, PartialEq)]
pub struct ExtentMap<E: ExpressionKind + Copy>(ConsistentMap<AxisKey, E>);
@@ -41,27 +48,27 @@ pub struct ExtentMap<E: ExpressionKind + Copy>(ConsistentMap<AxisKey, E>);
impl<E: ExpressionKind + Copy> ExtentMap<E> {
/// Parse an extent map from the function args.
///
- /// If `enforce` is true other arguments will create an error, otherwise
+ /// If `all` is true other arguments will create an error, otherwise
/// they are left intact.
- pub fn new(args: &mut FuncArgs, enforce: bool) -> ParseResult<ExtentMap<E>> {
+ pub fn new(args: &mut FuncArgs, all: bool) -> ParseResult<ExtentMap<E>> {
let mut map = ConsistentMap::new();
- for arg in args.keys() {
- let key = match arg.v.key.v.as_str() {
+ for arg in args.iter_keys() {
+ let key = match arg.key.v.as_str() {
"width" | "w" => AxisKey::Specific(Horizontal),
"height" | "h" => AxisKey::Specific(Vertical),
"primary-size" | "ps" => AxisKey::Generic(Primary),
"secondary-size" | "ss" => AxisKey::Generic(Secondary),
- _ => if enforce {
+ _ => if all {
error!("expected dimension")
} else {
- args.add_key(arg);
+ args.add_key_pair(arg);
continue;
}
};
- let e = E::from_expr(arg.v.value)?;
+ let e = E::from_expr(arg.value)?;
map.add(key, e)?;
}
@@ -98,9 +105,9 @@ impl<E: ExpressionKind + Copy> PosAxisMap<E> {
map.add_opt(PosAxisKey::First, args.get_pos_opt::<E>()?)?;
map.add_opt(PosAxisKey::Second, args.get_pos_opt::<E>()?)?;
- for arg in args.keys() {
- let axis = AxisKey::from_ident(&arg.v.key)?;
- let value = E::from_expr(arg.v.value)?;
+ for arg in args.iter_keys() {
+ let axis = AxisKey::from_ident(&arg.key)?;
+ let value = E::from_expr(arg.value)?;
map.add(PosAxisKey::Keyword(axis), value)?;
}
diff --git a/src/library/maps/mod.rs b/src/library/maps/mod.rs
index 5e130d53..a868ce6c 100644
--- a/src/library/maps/mod.rs
+++ b/src/library/maps/mod.rs
@@ -36,6 +36,37 @@ pub_use_mod!(axis);
pub_use_mod!(alignment);
pub_use_mod!(padding);
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub enum DefaultKey<T> {
+ Some(T),
+ None,
+}
+
+impl<T> Into<Option<T>> for DefaultKey<T> {
+ fn into(self) -> Option<T> {
+ match self {
+ DefaultKey::Some(v) => Some(v),
+ DefaultKey::None => None,
+ }
+ }
+}
+
+impl<T> ExpressionKind for DefaultKey<T> where T: ExpressionKind {
+ const NAME: &'static str = T::NAME;
+
+ fn from_expr(expr: Spanned<Expression>) -> ParseResult<DefaultKey<T>> {
+ if let Expression::Ident(ident) = &expr.v {
+ match ident.as_str() {
+ "default" => return Ok(DefaultKey::None),
+ _ => {},
+ }
+ }
+
+ T::from_expr(expr).map(|v| DefaultKey::Some(v))
+ }
+}
+
/// A deduplicating map type useful for storing possibly redundant arguments.
#[derive(Debug, Clone, PartialEq)]
pub struct ConsistentMap<K, V> where K: Hash + Eq {
@@ -95,10 +126,3 @@ impl<K, V> ConsistentMap<K, V> where K: Hash + Eq {
self.map.iter()
}
}
-
-key!(Direction, "direction",
- "left-to-right" | "ltr" => LeftToRight,
- "right-to-left" | "rtl" => RightToLeft,
- "top-to-bottom" | "ttb" => TopToBottom,
- "bottom-to-top" | "btt" => BottomToTop,
-);
diff --git a/src/library/maps/padding.rs b/src/library/maps/padding.rs
index 4bbbb754..e2d0ea09 100644
--- a/src/library/maps/padding.rs
+++ b/src/library/maps/padding.rs
@@ -46,11 +46,12 @@ impl PaddingMap {
/// Parse a padding map from the function args.
pub fn new(args: &mut FuncArgs) -> ParseResult<PaddingMap> {
let mut map = ConsistentMap::new();
- map.add_opt(PaddingKey::All, args.get_pos_opt::<Option<PSize>>()?)?;
+ map.add_opt(PaddingKey::All,
+ args.get_pos_opt::<DefaultKey<PSize>>()?.map(Into::into))?;
- for arg in args.keys() {
- let key = PaddingKey::from_ident(&arg.v.key)?;
- let size = Option::<PSize>::from_expr(arg.v.value)?;
+ for arg in args.iter_keys() {
+ let key = PaddingKey::from_ident(&arg.key)?;
+ let size = DefaultKey::<PSize>::from_expr(arg.value)?.into();
map.add(key, size)?;
}