summaryrefslogtreecommitdiff
path: root/src/syntax/value.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-15 11:44:18 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-15 11:44:18 +0200
commit1a0608930cea9c939319ae4b6e2c793eaf2f10d0 (patch)
treee8a8a157a40fa2198b5db5066e91fa8ecb5e16e6 /src/syntax/value.rs
parentd90d921a910e52242c68a91ff3ff03749250253c (diff)
Rename Value trait into TryFromExpr ✒
Diffstat (limited to 'src/syntax/value.rs')
-rw-r--r--src/syntax/value.rs197
1 files changed, 0 insertions, 197 deletions
diff --git a/src/syntax/value.rs b/src/syntax/value.rs
deleted file mode 100644
index aa5049e0..00000000
--- a/src/syntax/value.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-//! Value types for extracting function arguments.
-
-use fontdock::{FontStyle, FontWeight, FontWidth};
-
-use crate::layout::{Dir, SpecAlign};
-use crate::length::{Length, ScaleLength};
-use crate::paper::Paper;
-use crate::Feedback;
-use super::expr::*;
-use super::span::Spanned;
-use super::tree::SyntaxTree;
-
-/// Value types are used to extract values from functions, tuples and
-/// objects. They represent the value part of an argument.
-///
-/// # Example
-/// ```typst
-/// [func: 12pt, key="these are both values"]
-/// ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
-/// ```
-pub trait Value: Sized {
- /// Try to parse this value from an expression.
- ///
- /// Returns `None` and generates an appropriate error if the expression is
- /// not valid for this value type
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self>;
-}
-
-impl<V: Value> Value for Spanned<V> {
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self> {
- let span = expr.span;
- V::parse(expr, f).map(|v| Spanned { v, span })
- }
-}
-
-macro_rules! match_value {
- ($type:ty, $name:expr, $($p:pat => $r:expr),* $(,)?) => {
- impl Value for $type {
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self> {
- #[allow(unreachable_patterns)]
- match expr.v {
- $($p => Some($r)),*,
- other => {
- error!(
- @f, expr.span,
- "expected {}, found {}", $name, other.name()
- );
- None
- }
- }
- }
- }
- };
-}
-
-match_value!(Expr, "expression", e => e);
-match_value!(Ident, "identifier", Expr::Ident(i) => i);
-match_value!(String, "string", Expr::Str(s) => s);
-match_value!(bool, "bool", Expr::Bool(b) => b);
-match_value!(f64, "number", Expr::Number(n) => n);
-match_value!(Length, "length", Expr::Length(l) => l);
-match_value!(SyntaxTree, "tree", Expr::Tree(t) => t);
-match_value!(Tuple, "tuple", Expr::Tuple(t) => t);
-match_value!(Object, "object", Expr::Object(o) => o);
-match_value!(ScaleLength, "number or length",
- Expr::Length(length) => ScaleLength::Absolute(length),
- Expr::Number(scale) => ScaleLength::Scaled(scale),
-);
-
-/// A value type that matches identifiers and strings and implements
-/// `Into<String>`.
-pub struct StringLike(pub String);
-
-impl From<StringLike> for String {
- fn from(like: StringLike) -> String {
- like.0
- }
-}
-
-match_value!(StringLike, "identifier or string",
- Expr::Ident(Ident(s)) => StringLike(s),
- Expr::Str(s) => StringLike(s),
-);
-
-macro_rules! ident_value {
- ($type:ty, $name:expr, $parse:expr) => {
- impl Value for $type {
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self> {
- if let Expr::Ident(ident) = expr.v {
- let val = $parse(ident.as_str());
- if val.is_none() {
- error!(@f, expr.span, "invalid {}", $name);
- }
- val
- } else {
- error!(
- @f, expr.span,
- "expected {}, found {}", $name, expr.v.name()
- );
- None
- }
- }
- }
- };
-}
-
-ident_value!(Dir, "direction", |s| match s {
- "ltr" => Some(Self::LTR),
- "rtl" => Some(Self::RTL),
- "ttb" => Some(Self::TTB),
- "btt" => Some(Self::BTT),
- _ => None,
-});
-
-ident_value!(SpecAlign, "alignment", |s| match s {
- "left" => Some(Self::Left),
- "right" => Some(Self::Right),
- "top" => Some(Self::Top),
- "bottom" => Some(Self::Bottom),
- "center" => Some(Self::Center),
- _ => None,
-});
-
-ident_value!(FontStyle, "font style", FontStyle::from_name);
-ident_value!(Paper, "paper", Paper::from_name);
-
-impl Value for FontWeight {
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self> {
- match expr.v {
- Expr::Number(weight) => {
- const MIN: u16 = 100;
- const MAX: u16 = 900;
-
- Some(Self(if weight < MIN as f64 {
- error!(@f, expr.span, "the minimum font weight is {}", MIN);
- MIN
- } else if weight > MAX as f64 {
- error!(@f, expr.span, "the maximum font weight is {}", MAX);
- MAX
- } else {
- weight.round() as u16
- }))
- }
- Expr::Ident(ident) => {
- let weight = Self::from_name(ident.as_str());
- if weight.is_none() {
- error!(@f, expr.span, "invalid font weight");
- }
- weight
- }
- other => {
- error!(
- @f, expr.span,
- "expected font weight (name or number), found {}",
- other.name(),
- );
- None
- }
- }
- }
-}
-
-impl Value for FontWidth {
- fn parse(expr: Spanned<Expr>, f: &mut Feedback) -> Option<Self> {
- match expr.v {
- Expr::Number(width) => {
- const MIN: u16 = 1;
- const MAX: u16 = 9;
-
- Self::new(if width < MIN as f64 {
- error!(@f, expr.span, "the minimum font width is {}", MIN);
- MIN
- } else if width > MAX as f64 {
- error!(@f, expr.span, "the maximum font width is {}", MAX);
- MAX
- } else {
- width.round() as u16
- })
- }
- Expr::Ident(ident) => {
- let width = Self::from_name(ident.as_str());
- if width.is_none() {
- error!(@f, expr.span, "invalid font width");
- }
- width
- }
- other => {
- error!(
- @f, expr.span,
- "expected font width (name or number), found {}",
- other.name(),
- );
- None
- }
- }
- }
-}