summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/maps/axis.rs27
-rw-r--r--src/library/maps/mod.rs38
-rw-r--r--src/library/maps/padding.rs9
-rw-r--r--src/library/mod.rs18
4 files changed, 63 insertions, 29 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)?;
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 92c3c948..f8625904 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -62,7 +62,7 @@ function! {
FontFamilyFunc {
body: parse!(optional: body, ctx),
list: {
- args.pos().map(|arg| match arg.v {
+ args.iter_pos().map(|arg| match arg.v {
Expression::Str(s) |
Expression::Ident(Ident(s)) => Ok(s.to_lowercase()),
_ => error!("expected identifier or string"),
@@ -118,7 +118,7 @@ function! {
FontWeightFunc {
body: parse!(optional: body, ctx),
weight: match args.get_pos::<Expression>()? {
- Expression::Num(weight) => {
+ Expression::Number(weight) => {
let weight = weight.round() as i16;
FontWeight(
if weight < 100 { 100 }
@@ -264,13 +264,15 @@ function! {
axis: AxisKey::Specific(axis),
spacing: FSize::from_expr(args.get_pos::<Spanned<Expression>>()?)?,
}
- } else if let Some(arg) = args.get_key_next() {
- let axis = AxisKey::from_ident(&arg.v.key)
- .map_err(|_| error!(@unexpected_argument))?;
-
- let spacing = FSize::from_expr(arg.v.value)?;
- SpacingFunc { axis, spacing }
} else {
+ for arg in args.iter_keys() {
+ let axis = AxisKey::from_ident(&arg.key)
+ .map_err(|_| error!(@unexpected_argument))?;
+
+ let spacing = FSize::from_expr(arg.value)?;
+ return Ok(SpacingFunc { axis, spacing });
+ }
+
error!("expected axis and spacing")
}
}