diff options
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/maps/axis.rs | 27 | ||||
| -rw-r--r-- | src/library/maps/mod.rs | 38 | ||||
| -rw-r--r-- | src/library/maps/padding.rs | 9 | ||||
| -rw-r--r-- | src/library/mod.rs | 18 |
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") } } |
