summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/func/args.rs10
-rw-r--r--src/func/macros.rs23
-rw-r--r--src/func/mod.rs5
-rw-r--r--src/layout/flex.rs3
-rw-r--r--src/layout/mod.rs21
-rw-r--r--src/layout/stack.rs3
-rw-r--r--src/layout/text.rs2
-rw-r--r--src/layout/tree.rs2
-rw-r--r--src/lib.rs43
-rw-r--r--src/library/align.rs2
-rw-r--r--src/library/boxed.rs2
-rw-r--r--src/library/mod.rs8
-rw-r--r--src/syntax/mod.rs2
-rw-r--r--src/syntax/parsing.rs39
14 files changed, 68 insertions, 97 deletions
diff --git a/src/func/args.rs b/src/func/args.rs
index 2e9e80cc..d1d49b6a 100644
--- a/src/func/args.rs
+++ b/src/func/args.rs
@@ -64,14 +64,14 @@ impl<'a> ArgParser<'a> {
if self.positional_index == self.args.positional.len() {
Ok(())
} else {
- pr!("unexpected argument");
+ 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(|| pr!(@"expected {}", T::ERROR_MESSAGE))
+ val.ok_or_else(|| error!(@"expected {}", T::ERROR_MESSAGE))
}
}
@@ -93,10 +93,10 @@ macro_rules! arg {
const ERROR_MESSAGE: &'static str = $err;
fn from_expr(expr: &'a Spanned<Expression>) -> ParseResult<Spanned<Self::Output>> {
- #[allow(unreachable_patterns)]
+ #[allow(unreachable_code)]
match &expr.val {
$wanted => Ok(Spanned::new($converted, expr.span)),
- _ => pr!("expected {}", $err),
+ _ => error!("expected {}", $err),
}
}
}
@@ -179,7 +179,7 @@ impl AlignmentKey {
Right if horizontal => axes.right(),
Top if !horizontal => axes.top(),
Bottom if !horizontal => axes.bottom(),
- _ => lr!(
+ _ => error!(
"invalid alignment `{}` for {} axis",
format!("{:?}", self).to_lowercase(),
format!("{:?}", axis).to_lowercase()
diff --git a/src/func/macros.rs b/src/func/macros.rs
index 78cf1f56..0ffdc857 100644
--- a/src/func/macros.rs
+++ b/src/func/macros.rs
@@ -111,7 +111,7 @@ macro_rules! function {
macro_rules! parse {
(forbidden: $body:expr) => {
if $body.is_some() {
- pr!("unexpected body");
+ error!("unexpected body");
}
};
@@ -127,23 +127,16 @@ macro_rules! parse {
if let Some(body) = $body {
$crate::syntax::parse(body, $ctx)?
} else {
- pr!("expected body");
+ error!("expected body");
}
)
}
-/// Early-return with a formatted parsing error or yield
-/// an error expression without returning when prefixed with `@`.
+/// Early-return with a formatted typesetting error or construct an error
+/// expression without returning when prefixed with `@`.
#[macro_export]
-macro_rules! pr {
- (@$($tts:tt)*) => ($crate::syntax::ParseError::new(format!($($tts)*)));
- ($($tts:tt)*) => (return Err(pr!(@$($tts)*)););
-}
-
-/// Early-return with a formatted layouting error or yield
-/// an error expression without returning when prefixed with `@`.
-#[macro_export]
-macro_rules! lr {
- (@$($tts:tt)*) => ($crate::layout::LayoutError::new(format!($($tts)*)));
- ($($tts:tt)*) => (return Err(lr!(@$($tts)*)););
+macro_rules! error {
+ (@unexpected_argument) => (error!(@"unexpected argument"));
+ (@$($tts:tt)*) => ($crate::TypesetError::with_message(format!($($tts)*)));
+ ($($tts:tt)*) => (return Err(error!(@$($tts)*)););
}
diff --git a/src/func/mod.rs b/src/func/mod.rs
index b16eecb8..31e31592 100644
--- a/src/func/mod.rs
+++ b/src/func/mod.rs
@@ -16,7 +16,7 @@ pub mod prelude {
pub use super::args::*;
pub use super::{Scope, ParseFunc, LayoutFunc, Command, Commands};
pub use crate::syntax::{SyntaxTree, FuncHeader, FuncArgs, Expression, Spanned, Span};
- pub use crate::syntax::{parse, ParseContext, ParseError, ParseResult};
+ pub use crate::syntax::{parse, ParseContext, ParseResult};
pub use crate::size::{Size, Size2D, SizeBox};
pub use crate::style::{PageStyle, TextStyle};
pub use crate::layout::{
@@ -24,8 +24,7 @@ pub mod prelude {
LayoutContext, LayoutSpace, LayoutSpaces,
LayoutAxes, Axis, GenericAxisKind, SpecificAxisKind,
LayoutAlignment, Alignment,
- SpacingKind,
- LayoutError, LayoutResult,
+ SpacingKind, LayoutResult,
};
}
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 3e8a64e1..46d66951 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -230,7 +230,8 @@ impl FlexLayouter {
while size.x > self.line.usable {
if self.stack.space_is_last() {
- lr!("box does not fit into line");
+ error!("box of size {} does not fit into line of size {}",
+ size.x, self.line.usable);
}
self.stack.finish_space(true);
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 4304e46e..690e91b7 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -5,8 +5,8 @@ use std::io::{self, Write};
use smallvec::SmallVec;
use toddle::query::{FontClass, SharedFontLoader};
-use toddle::Error as FontError;
+use crate::TypesetResult;
use crate::func::Command;
use crate::size::{Size, Size2D, SizeBox};
use crate::style::{LayoutStyle, TextStyle};
@@ -366,22 +366,5 @@ impl Serialize for MultiLayout {
}
}
-/// The error type for layouting.
-pub struct LayoutError(String);
-
/// The result type for layouting.
-pub type LayoutResult<T> = Result<T, LayoutError>;
-
-impl LayoutError {
- /// Create a new layout error with a message.
- pub fn new<S: Into<String>>(message: S) -> LayoutError {
- LayoutError(message.into())
- }
-}
-
-error_type! {
- err: LayoutError,
- show: f => f.write_str(&err.0),
- from: (std::io::Error, LayoutError::new(err.to_string())),
- from: (FontError, LayoutError::new(err.to_string())),
-}
+pub type LayoutResult<T> = TypesetResult<T>;
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index 64823b67..176aa261 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -108,7 +108,8 @@ impl StackLayouter {
// Find the first (sub-)space that fits the layout.
while !self.sub.usable.fits(new_size) {
if self.space_is_last() && self.space_is_empty() {
- lr!("box does not fit into stack");
+ error!("box of size {} does not fit into remaining stack of size {}",
+ size, self.sub.usable - Size2D::with_y(self.sub.size.y));
}
self.finish_space(true);
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 514bfe92..8a0e7cec 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -116,6 +116,6 @@ impl<'a, 'p> TextLayouter<'a, 'p> {
self.classes.pop();
}
- lr!("no suitable font for character `{}`", c);
+ error!("no suitable font for character `{}`", c);
}
}
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index 5fe3b6fd..c9d40e93 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -111,7 +111,7 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
SetTextStyle(style) => self.style.text = style,
SetPageStyle(style) => {
if !self.ctx.top_level {
- lr!("page style cannot only be altered in the top-level context");
+ error!("the page style cannot only be altered from a top-level context");
}
self.style.page = style;
diff --git a/src/lib.rs b/src/lib.rs
index 7b6c4012..3369d01c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -18,13 +18,15 @@ pub extern crate toddle;
use std::cell::RefCell;
use smallvec::smallvec;
+
use toddle::query::{FontLoader, FontProvider, SharedFontLoader};
+use toddle::Error as FontError;
use crate::func::Scope;
use crate::layout::{layout_tree, MultiLayout, LayoutContext};
use crate::layout::{LayoutAxes, LayoutAlignment, Axis, Alignment};
-use crate::layout::{LayoutError, LayoutResult, LayoutSpace};
-use crate::syntax::{SyntaxTree, parse, ParseContext, ParseError, ParseResult};
+use crate::layout::{LayoutResult, LayoutSpace};
+use crate::syntax::{parse, SyntaxTree, ParseContext, Span, ParseResult};
use crate::style::{LayoutStyle, PageStyle, TextStyle};
#[macro_use]
@@ -116,24 +118,31 @@ impl<'p> Typesetter<'p> {
}
}
-/// The general error type for typesetting.
-pub enum TypesetError {
- /// An error that occured in the parsing step.
- Parse(ParseError),
- /// An error that occured in the layouting step.
- Layout(LayoutError),
+/// The result type for typesetting.
+pub type TypesetResult<T> = Result<T, TypesetError>;
+
+/// The error type for typesetting.
+pub struct TypesetError {
+ message: String,
+ span: Option<Span>,
+}
+
+impl TypesetError {
+ /// Create a new typesetting error.
+ pub fn with_message(message: String) -> TypesetError {
+ TypesetError { message, span: None }
+ }
}
error_type! {
err: TypesetError,
- show: f => match err {
- TypesetError::Parse(e) => write!(f, "{}", e),
- TypesetError::Layout(e) => write!(f, "{}", e),
- },
- source: match err {
- TypesetError::Parse(e) => Some(e),
- TypesetError::Layout(e) => Some(e),
+ show: f => {
+ write!(f, "{}", err.message)?;
+ if let Some(span) = err.span {
+ write!(f, " at {}", span)?;
+ }
+ Ok(())
},
- from: (ParseError, TypesetError::Parse(err)),
- from: (LayoutError, TypesetError::Layout(err)),
+ from: (std::io::Error, TypesetError::with_message(err.to_string())),
+ from: (FontError, TypesetError::with_message(err.to_string())),
}
diff --git a/src/library/align.rs b/src/library/align.rs
index 14e329e3..417d8f07 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -19,7 +19,7 @@ function! {
"vertical" => Key::Axis(AxisKey::Vertical),
"primary" => Key::Axis(AxisKey::Primary),
"secondary" => Key::Axis(AxisKey::Secondary),
- _ => pr!("unexpected argument"),
+ _ => error!(unexpected_argument),
};
let value = AlignmentKey::parse(arg.val.1.val)?;
diff --git a/src/library/boxed.rs b/src/library/boxed.rs
index d4e39450..a2df45e3 100644
--- a/src/library/boxed.rs
+++ b/src/library/boxed.rs
@@ -17,7 +17,7 @@ function! {
"height" | "h" => AxisKey::Vertical,
"primary-size" => AxisKey::Primary,
"secondary-size" => AxisKey::Secondary,
- _ => pr!("unexpected argument"),
+ _ => error!(unexpected_argument),
};
let size = ArgParser::convert::<ArgSize>(arg.val.1.val)?;
diff --git a/src/library/mod.rs b/src/library/mod.rs
index b09303bb..02af0d83 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -128,7 +128,7 @@ function! {
"vertical-origin" => AxisAligned(AxisKey::Vertical, Origin),
"vertical-end" => AxisAligned(AxisKey::Vertical, End),
- _ => pr!("unexpected argument"),
+ _ => error!(unexpected_argument),
};
let size = ArgParser::convert::<ArgSize>(arg.val.1.val)?;
@@ -200,13 +200,13 @@ function! {
"vertical" => AxisKey::Vertical,
"primary" => AxisKey::Primary,
"secondary" => AxisKey::Secondary,
- _ => pr!("unexpected argument"),
+ _ => error!(unexpected_argument),
};
let spacing = SpacingValue::from_expr(arg.val.1.val)?;
Spacing { axis, spacing }
} else {
- pr!("expected axis and expression")
+ error!("expected axis and expression")
}
};
@@ -236,7 +236,7 @@ impl SpacingValue {
Ok(match expr.val {
Expression::Size(s) => SpacingValue::Absolute(*s),
Expression::Num(f) => SpacingValue::Relative(*f as f32),
- _ => pr!("invalid spacing: expected size or number"),
+ _ => error!("invalid spacing: expected size or number"),
})
}
}
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 33413317..1b55fb4e 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -12,7 +12,7 @@ mod span;
pub use span::{Span, Spanned};
pub use tokens::{tokenize, Tokens};
-pub use parsing::{parse, ParseContext, ParseError, ParseResult};
+pub use parsing::{parse, ParseContext, ParseResult};
/// A logical unit of the incoming text stream.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs
index b56094e1..2d76b6cf 100644
--- a/src/syntax/parsing.rs
+++ b/src/syntax/parsing.rs
@@ -2,6 +2,7 @@
use unicode_xid::UnicodeXID;
+use crate::TypesetResult;
use crate::func::{LayoutFunc, Scope};
use crate::size::Size;
use super::*;
@@ -69,7 +70,7 @@ impl<'s> Parser<'s> {
match token.val {
// Functions.
LeftBracket => self.parse_func()?,
- RightBracket => return Err(ParseError::new("unexpected closing bracket")),
+ RightBracket => error!("unexpected closing bracket"),
// Modifiers.
Underscore => self.append_consumed(Node::ToggleItalics, token.span),
@@ -120,10 +121,10 @@ impl<'s> Parser<'s> {
if is_identifier(word) {
Ok(Spanned::new(word.to_owned(), span))
} else {
- pr!("invalid identifier: '{}'", word);
+ error!("invalid identifier: `{}`", word);
}
}
- _ => pr!("expected identifier"),
+ _ => error!("expected identifier"),
}?;
self.skip_white();
@@ -132,7 +133,7 @@ impl<'s> Parser<'s> {
let args = match self.tokens.next().map(Spanned::value) {
Some(Token::RightBracket) => FuncArgs::new(),
Some(Token::Colon) => self.parse_func_args()?,
- _ => pr!("expected arguments or closing bracket"),
+ _ => error!("expected arguments or closing bracket"),
};
let end = self.tokens.string_index();
@@ -158,7 +159,7 @@ impl<'s> Parser<'s> {
match self.tokens.next().map(Spanned::value) {
Some(Token::Comma) => {},
Some(Token::RightBracket) => break,
- _ => pr!("expected comma or closing bracket"),
+ _ => error!("expected comma or closing bracket"),
}
}
@@ -183,7 +184,7 @@ impl<'s> Parser<'s> {
self.skip_white();
let name = token.span_map(|_| name.to_string());
- let next = self.tokens.next().ok_or_else(|| pr!(@"expected value"))?;
+ let next = self.tokens.next().ok_or_else(|| error!(@"expected expression"))?;
let val = Self::parse_expression(next)?;
let span = Span::merge(name.span, val.span);
@@ -218,8 +219,7 @@ impl<'s> Parser<'s> {
Expression::Ident(text.to_owned())
}
}
-
- _ => pr!("expected expression"),
+ _ => error!("expected expression"),
}, token.span))
}
@@ -231,7 +231,7 @@ impl<'s> Parser<'s> {
.ctx
.scope
.get_parser(&header.name.val)
- .ok_or_else(|| pr!(@"unknown function: '{}'", &header.name.val))?;
+ .ok_or_else(|| error!(@"unknown function: `{}`", &header.name.val))?;
let has_body = self.tokens.peek().map(Spanned::value) == Some(Token::LeftBracket);
@@ -243,7 +243,7 @@ impl<'s> Parser<'s> {
let start = self.tokens.string_index();
let end = find_closing_bracket(&self.src[start..])
.map(|end| start + end)
- .ok_or_else(|| ParseError::new("expected closing bracket"))?;
+ .ok_or_else(|| error!(@"expected closing bracket"))?;
// Parse the body.
let body_string = &self.src[start..end];
@@ -299,7 +299,7 @@ impl<'s> Parser<'s> {
state = NewlineState::Zero;
match token.val {
Token::LineComment(_) | Token::BlockComment(_) => self.advance(),
- Token::StarSlash => pr!("unexpected end of block comment"),
+ Token::StarSlash => error!("unexpected end of block comment"),
_ => break,
}
}
@@ -431,23 +431,8 @@ fn is_identifier(string: &str) -> bool {
true
}
-/// The error type for parsing.
-pub struct ParseError(String);
-
/// The result type for parsing.
-pub type ParseResult<T> = Result<T, ParseError>;
-
-impl ParseError {
- /// Create a new parse error with a message.
- pub fn new<S: Into<String>>(message: S) -> ParseError {
- ParseError(message.into())
- }
-}
-
-error_type! {
- err: ParseError,
- show: f => f.write_str(&err.0),
-}
+pub type ParseResult<T> = TypesetResult<T>;
#[cfg(test)]