summaryrefslogtreecommitdiff
path: root/src/func/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/func/args.rs')
-rw-r--r--src/func/args.rs215
1 files changed, 0 insertions, 215 deletions
diff --git a/src/func/args.rs b/src/func/args.rs
deleted file mode 100644
index d1d49b6a..00000000
--- a/src/func/args.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-//! Parsing, storing and deduplication of function arguments.
-
-use super::prelude::*;
-use Expression::*;
-
-/// Provides a convenient interface to parse the arguments to a function.
-pub struct ArgParser<'a> {
- args: &'a FuncArgs,
- positional_index: usize,
-}
-
-impl<'a> ArgParser<'a> {
- pub fn new(args: &'a FuncArgs) -> ArgParser<'a> {
- ArgParser {
- args,
- positional_index: 0,
- }
- }
-
- /// Get the next positional argument of the given type.
- ///
- /// If there are no more arguments or the type is wrong,
- /// this will return an error.
- pub fn get_pos<T>(&mut self) -> ParseResult<Spanned<T::Output>>
- where T: Argument<'a> {
- Self::expected(self.get_pos_opt::<T>()?)
- }
-
- /// Get the next positional argument if there is any.
- ///
- /// If the argument is of the wrong type, this will return an error.
- pub fn get_pos_opt<T>(&mut self) -> ParseResult<Option<Spanned<T::Output>>>
- where T: Argument<'a> {
- let arg = self.args.positional
- .get(self.positional_index)
- .map(T::from_expr)
- .transpose();
-
- if let Ok(Some(_)) = arg {
- self.positional_index += 1;
- }
-
- arg
- }
-
- /// Get a keyword argument with the given key and type.
- pub fn get_key<T>(&mut self, key: &str) -> ParseResult<Spanned<T::Output>>
- where T: Argument<'a> {
- Self::expected(self.get_key_opt::<T>(key)?)
- }
-
- /// Get a keyword argument with the given key and type if it is present.
- pub fn get_key_opt<T>(&mut self, key: &str) -> ParseResult<Option<Spanned<T::Output>>>
- where T: Argument<'a> {
- self.args.keyword.iter()
- .find(|entry| entry.val.0.val == key)
- .map(|entry| T::from_expr(&entry.val.1))
- .transpose()
- }
-
- /// Assert that there are no positional arguments left. Returns an error
- /// otherwise.
- pub fn done(&self) -> ParseResult<()> {
- if self.positional_index == self.args.positional.len() {
- Ok(())
- } else {
- error!(unexpected_argument);
- }
- }
-
- /// Covert an option to a result with an error on `None`.
- fn expected<T>(val: Option<Spanned<T::Output>>) -> ParseResult<Spanned<T::Output>>
- where T: Argument<'a> {
- val.ok_or_else(|| error!(@"expected {}", T::ERROR_MESSAGE))
- }
-}
-
-/// A kind of argument.
-pub trait Argument<'a> {
- type Output;
- const ERROR_MESSAGE: &'static str;
-
- fn from_expr(expr: &'a Spanned<Expression>) -> ParseResult<Spanned<Self::Output>>;
-}
-
-macro_rules! arg {
- ($type:ident, $err:expr, $doc:expr, $output:ty, $wanted:pat => $converted:expr) => (
- #[doc = $doc]
- #[doc = " argument for use with the [`ArgParser`]."]
- pub struct $type;
- impl<'a> Argument<'a> for $type {
- type Output = $output;
- const ERROR_MESSAGE: &'static str = $err;
-
- fn from_expr(expr: &'a Spanned<Expression>) -> ParseResult<Spanned<Self::Output>> {
- #[allow(unreachable_code)]
- match &expr.val {
- $wanted => Ok(Spanned::new($converted, expr.span)),
- _ => error!("expected {}", $err),
- }
- }
- }
- );
-}
-
-arg!(ArgExpr, "expression", "A generic expression", &'a Expression, expr => &expr);
-arg!(ArgIdent, "identifier", "An identifier (e.g. `horizontal`)", &'a str, Ident(s) => s.as_str());
-arg!(ArgStr, "string", "A string (e.g. `\"Hello\"`)", &'a str, Str(s) => s.as_str());
-arg!(ArgNum, "number", "A number (e.g. `5.4`)", f64, Num(n) => *n);
-arg!(ArgSize, "size", "A size (e.g. `12pt`)", crate::size::Size, Size(s) => *s);
-arg!(ArgBool, "bool", "A boolean (`true` or `false`)", bool, Bool(b) => *b);
-
-/// An argument key which identifies a layouting axis.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum AxisKey {
- Primary,
- Secondary,
- Vertical,
- Horizontal,
-}
-
-impl AxisKey {
- /// The generic version of this axis key in the given system of axes.
- pub fn generic(&self, axes: LayoutAxes) -> GenericAxisKind {
- match self {
- Primary => GenericAxisKind::Primary,
- Secondary => GenericAxisKind::Secondary,
- Vertical => axes.vertical(),
- Horizontal => axes.horizontal(),
- }
- }
-
- /// The specific version of this axis key in the given system of axes.
- pub fn specific(&self, axes: LayoutAxes) -> SpecificAxisKind {
- match self {
- Primary => axes.primary(),
- Secondary => axes.secondary(),
- Vertical => SpecificAxisKind::Vertical,
- Horizontal => SpecificAxisKind::Horizontal,
- }
- }
-}
-
-/// An argument key which identifies a target alignment.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum AlignmentKey {
- Left,
- Top,
- Right,
- Bottom,
- Origin,
- Center,
- End,
-}
-
-impl AlignmentKey {
- /// The generic axis this alignment key corresopnds to in the given system
- /// of layouting axes. Falls back to `default` if the alignment is generic.
- pub fn axis(&self, axes: LayoutAxes, default: GenericAxisKind) -> GenericAxisKind {
- use AlignmentKey::*;
- match self {
- Origin | Center | End => default,
- Left | Right => axes.horizontal(),
- Top | Bottom => axes.vertical(),
- }
- }
-
- /// The generic version of this alignment in the given system of layouting
- /// axes. Returns an error if the alignment is invalid for the given axis.
- pub fn generic(&self, axes: LayoutAxes, axis: GenericAxisKind) -> LayoutResult<Alignment> {
- use AlignmentKey::*;
-
- let horizontal = axis == axes.horizontal();
- Ok(match self {
- Origin => Alignment::Origin,
- Center => Alignment::Center,
- End => Alignment::End,
- Left if horizontal => axes.left(),
- Right if horizontal => axes.right(),
- Top if !horizontal => axes.top(),
- Bottom if !horizontal => axes.bottom(),
- _ => error!(
- "invalid alignment `{}` for {} axis",
- format!("{:?}", self).to_lowercase(),
- format!("{:?}", axis).to_lowercase()
- )
- })
- }
-
- /// The specific version of this alignment in the given system of layouting
- /// axes.
- pub fn specific(&self, axes: LayoutAxes, axis: SpecificAxisKind) -> AlignmentKey {
- use AlignmentKey::*;
- match (self, axis) {
- (Origin, SpecificAxisKind::Horizontal) => Left,
- (End, SpecificAxisKind::Horizontal) => Right,
- (Origin, SpecificAxisKind::Vertical) => Top,
- (End, SpecificAxisKind::Vertical) => Bottom,
- _ => *self,
- }
- }
-}
-
-/// An argument key which identifies a margin or padding target.
-///
-/// A is the axis type used.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum PaddingKey<A> {
- /// All four sides should have the specified padding.
- All,
- /// Both sides of the given axis should have the specified padding.
- Axis(A),
- /// Only the given side of the given axis should have the specified padding.
- AxisAligned(A, AlignmentKey),
-}