summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-03-14 16:26:06 +0100
committerLaurenz <laurmaedje@gmail.com>2019-03-14 17:10:06 +0100
commit22ea09d9c1fd342dcee13d153fedaf49a62db044 (patch)
treead2038ac9761aa82dff253895abc62ecb7093a9c /src
parentaae8a3a77e7c963767b5bd94148d06d86d9b24dd (diff)
Better error handling 🌍
Diffstat (limited to 'src')
-rw-r--r--src/engine.rs15
-rw-r--r--src/font.rs42
-rw-r--r--src/lib.rs36
-rw-r--r--src/parsing.rs30
-rw-r--r--src/pdf.rs59
5 files changed, 105 insertions, 77 deletions
diff --git a/src/engine.rs b/src/engine.rs
index 2fbb830b..5a6e27b0 100644
--- a/src/engine.rs
+++ b/src/engine.rs
@@ -132,15 +132,20 @@ impl<'s> Engine<'s> {
type TypeResult<T> = std::result::Result<T, TypesetError>;
/// The error type for typesetting.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct TypesetError {
- message: String,
-}
+pub enum TypesetError {}
impl error::Error for TypesetError {}
impl fmt::Display for TypesetError {
+ #[inline]
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ Ok(())
+ }
+}
+
+impl fmt::Debug for TypesetError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str(&self.message)
+ fmt::Display::fmt(self, f)
}
}
diff --git a/src/font.rs b/src/font.rs
index ea59bd38..40fa2102 100644
--- a/src/font.rs
+++ b/src/font.rs
@@ -5,9 +5,9 @@ use std::error;
use std::fmt;
use std::io::{self, Cursor, Seek, SeekFrom};
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
-use opentype::{OpenTypeReader, Outlines, TableRecord, Tag};
-use opentype::tables::{Header, MacStyleFlags, Name, NameEntry, CharMap,
- MaximumProfile, HorizontalMetrics, Post, OS2};
+use opentype::{Error as OpentypeError, OpenTypeReader, Outlines, TableRecord, Tag};
+use opentype::tables::{Header, Name, CharMap, MaximumProfile, HorizontalMetrics, Post, OS2};
+use opentype::tables::{MacStyleFlags, NameEntry};
use crate::doc::Size;
@@ -588,8 +588,7 @@ impl<T> TakeInvalid<T> for Option<T> {
type FontResult<T> = Result<T, FontError>;
-/// The error type for font subsetting.
-#[derive(Debug)]
+/// The error type for font operations.
pub enum FontError {
/// The font file is incorrect.
InvalidFont(String),
@@ -601,9 +600,6 @@ pub enum FontError {
MissingCharacter(char),
/// An I/O Error occured while reading the font program.
Io(io::Error),
-
- #[doc(hidden)]
- __Extensible,
}
impl error::Error for FontError {
@@ -619,18 +615,23 @@ impl error::Error for FontError {
impl fmt::Display for FontError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use FontError::*;
match self {
- InvalidFont(message) => write!(f, "invalid font: {}", message),
- MissingTable(table) => write!(f, "missing table: {}", table),
- UnsupportedTable(table) => write!(f, "unsupported table: {}", table),
- MissingCharacter(c) => write!(f, "missing character: '{}'", c),
- Io(err) => fmt::Display::fmt(err, f),
- __Extensible => panic!("tried to display extensible variant"),
+ FontError::InvalidFont(message) => write!(f, "invalid font: {}", message),
+ FontError::MissingTable(table) => write!(f, "missing table: {}", table),
+ FontError::UnsupportedTable(table) => write!(f, "unsupported table: {}", table),
+ FontError::MissingCharacter(c) => write!(f, "missing character: '{}'", c),
+ FontError::Io(err) => write!(f, "io error: {}", err),
}
}
}
+impl fmt::Debug for FontError {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
+
impl From<io::Error> for FontError {
#[inline]
fn from(err: io::Error) -> FontError {
@@ -638,13 +639,12 @@ impl From<io::Error> for FontError {
}
}
-impl From<opentype::Error> for FontError {
- fn from(err: opentype::Error) -> FontError {
- use opentype::Error::*;
+impl From<OpentypeError> for FontError {
+ fn from(err: OpentypeError) -> FontError {
match err {
- InvalidFont(message) => FontError::InvalidFont(message),
- MissingTable(tag) => FontError::MissingTable(tag.to_string()),
- Io(err) => FontError::Io(err),
+ OpentypeError::InvalidFont(message) => FontError::InvalidFont(message),
+ OpentypeError::MissingTable(tag) => FontError::MissingTable(tag.to_string()),
+ OpentypeError::Io(err) => FontError::Io(err),
_ => panic!("unexpected extensible variant"),
}
}
diff --git a/src/lib.rs b/src/lib.rs
index 29daa853..6f2aaa53 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,17 +7,17 @@
//! ```
//! use typeset::Compiler;
//!
+//! // Minimal source code for our document.
+//! let src = "Hello World from Typeset!";
+//!
//! // Create an output file.
//! # /*
//! let mut file = std::fs::File::create("hello-typeset.pdf").unwrap();
//! # */
//! # let mut file = std::fs::File::create("../target/typeset-hello.pdf").unwrap();
//!
-//! // Create a compiler and export a PDF.
-//! let src = "Hello World from Typeset!";
+//! // Create a compiler and write the document into a file as a PDF.
//! let compiler = Compiler::new();
-//!
-//! // Write the document into a file as a PDF.
//! compiler.write_pdf(src, &mut file).unwrap();
//! ```
@@ -31,7 +31,7 @@ mod utility;
pub use crate::parsing::{Tokens, ParseError};
pub use crate::engine::TypesetError;
-pub use crate::pdf::PdfWritingError;
+pub use crate::pdf::PdfError;
use std::error;
use std::fmt;
@@ -74,8 +74,8 @@ impl Compiler {
/// Return the abstract syntax tree representation of the document.
#[inline]
- pub fn parse<'s>(&self, source: &'s str) -> Result<SyntaxTree<'s>, Error> {
- Parser::new(self.tokenize(source)).parse().map_err(Into::into)
+ pub fn parse<'s>(&self, source: &'s str) -> Result<SyntaxTree<'s>, ParseError> {
+ Parser::new(self.tokenize(source)).parse()
}
/// Return the abstract typesetted representation of the document.
@@ -92,8 +92,7 @@ impl Compiler {
}
}
-/// The error type for compilation.
-#[derive(Debug, Clone, Eq, PartialEq)]
+/// The general error type for compilation.
pub enum Error {
/// An error that occured while transforming source code into
/// an abstract syntax tree.
@@ -101,7 +100,7 @@ pub enum Error {
/// An error that occured while typesetting into an abstract document.
Typeset(TypesetError),
/// An error that occured while writing the document as a _PDF_.
- PdfWrite(PdfWritingError)
+ Pdf(PdfError),
}
impl error::Error for Error {
@@ -110,7 +109,7 @@ impl error::Error for Error {
match self {
Error::Parse(err) => Some(err),
Error::Typeset(err) => Some(err),
- Error::PdfWrite(err) => Some(err),
+ Error::Pdf(err) => Some(err),
}
}
}
@@ -121,11 +120,18 @@ impl fmt::Display for Error {
match self {
Error::Parse(err) => write!(f, "parse error: {}", err),
Error::Typeset(err) => write!(f, "typeset error: {}", err),
- Error::PdfWrite(err) => write!(f, "typeset error: {}", err),
+ Error::Pdf(err) => write!(f, "pdf error: {}", err),
}
}
}
+impl fmt::Debug for Error {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
+
impl From<ParseError> for Error {
#[inline]
fn from(err: ParseError) -> Error {
@@ -140,10 +146,10 @@ impl From<TypesetError> for Error {
}
}
-impl From<PdfWritingError> for Error {
+impl From<PdfError> for Error {
#[inline]
- fn from(err: PdfWritingError) -> Error {
- Error::PdfWrite(err)
+ fn from(err: PdfError) -> Error {
+ Error::Pdf(err)
}
}
diff --git a/src/parsing.rs b/src/parsing.rs
index 37c83b3f..5122597f 100644
--- a/src/parsing.rs
+++ b/src/parsing.rs
@@ -359,7 +359,6 @@ impl<'s, T> Parser<'s, T> where T: Iterator<Item = Token<'s>> {
type ParseResult<T> = std::result::Result<T, ParseError>;
/// The error type for parsing.
-#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ParseError {
/// A message describing the error.
message: String,
@@ -368,11 +367,18 @@ pub struct ParseError {
impl error::Error for ParseError {}
impl fmt::Display for ParseError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&self.message)
}
}
+impl fmt::Debug for ParseError {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
#[cfg(test)]
mod token_tests {
@@ -491,12 +497,12 @@ mod parse_tests {
/// Test if the source code parses into the syntax tree.
fn test(src: &str, tree: SyntaxTree) {
- assert_eq!(Parser::new(Tokens::new(src)).parse(), Ok(tree));
+ assert_eq!(Parser::new(Tokens::new(src)).parse().unwrap(), tree);
}
/// Test if the source parses into the error.
- fn test_err(src: &str, err: ParseError) {
- assert_eq!(Parser::new(Tokens::new(src)).parse(), Err(err));
+ fn test_err(src: &str, err: &str) {
+ assert_eq!(Parser::new(Tokens::new(src)).parse().unwrap_err().message, err);
}
/// Short cut macro to create a syntax tree.
@@ -577,17 +583,9 @@ mod parse_tests {
/// Tests whether errors get reported correctly.
#[test]
fn parse_errors() {
- test_err("No functions here]", ParseError {
- message: "unexpected closing bracket".to_owned(),
- });
- test_err("[hello][world", ParseError {
- message: "expected closing bracket".to_owned(),
- });
- test_err("[hello world", ParseError {
- message: "expected closing bracket".to_owned(),
- });
- test_err("[ no-name][Why?]", ParseError {
- message: "expected identifier".to_owned(),
- });
+ test_err("No functions here]", "unexpected closing bracket");
+ test_err("[hello][world", "expected closing bracket");
+ test_err("[hello world", "expected closing bracket");
+ test_err("[ no-name][Why?]", "expected identifier");
}
}
diff --git a/src/pdf.rs b/src/pdf.rs
index 4cd78d0a..b188ab91 100644
--- a/src/pdf.rs
+++ b/src/pdf.rs
@@ -4,12 +4,12 @@ use std::collections::HashSet;
use std::error;
use std::fmt;
use std::io::{self, Write};
-use pdf::{PdfWriter, Reference, Rect, Version, Trailer};
-use pdf::{DocumentCatalog, PageTree, Page, Resource, Text, Content};
-use pdf::font::{Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo,
- WidthRecord, FontDescriptor, FontFlags, EmbeddedFont, GlyphUnit};
+use pdf::{PdfWriter, Reference, Rect, Version, Trailer, DocumentCatalog};
+use pdf::{PageTree, Page, Resource, Text, Content};
+use pdf::font::{Type0Font, CMapEncoding, CIDFont, CIDFontType, CIDSystemInfo};
+use pdf::font::{WidthRecord, FontDescriptor, FontFlags, EmbeddedFont, GlyphUnit};
use crate::doc::{Document, Size, Text as DocText, TextCommand as DocTextCommand};
-use crate::font::Font;
+use crate::font::{Font, FontError};
/// Writes documents in the _PDF_ format.
@@ -279,34 +279,53 @@ impl std::ops::Deref for PdfFont {
}
/// Result type used for parsing.
-type PdfResult<T> = std::result::Result<T, PdfWritingError>;
+type PdfResult<T> = std::result::Result<T, PdfError>;
/// The error type for _PDF_ creation.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct PdfWritingError {
- /// A message describing the error.
- message: String,
+pub enum PdfError {
+ /// An error occured while subsetting the font for the _PDF_.
+ Font(FontError),
+ /// An I/O Error on the underlying writable occured.
+ Io(io::Error),
}
-impl error::Error for PdfWritingError {}
-
-impl From<io::Error> for PdfWritingError {
+impl error::Error for PdfError {
#[inline]
- fn from(err: io::Error) -> PdfWritingError {
- PdfWritingError { message: format!("{}", err) }
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match self {
+ PdfError::Font(err) => Some(err),
+ PdfError::Io(err) => Some(err),
+ }
}
}
-impl From<crate::font::FontError> for PdfWritingError {
+impl fmt::Display for PdfError {
#[inline]
- fn from(err: crate::font::FontError) -> PdfWritingError {
- PdfWritingError { message: format!("{}", err) }
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ PdfError::Font(err) => write!(f, "font error: {}", err),
+ PdfError::Io(err) => write!(f, "io error: {}", err),
+ }
}
}
-impl fmt::Display for PdfWritingError {
+impl fmt::Debug for PdfError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str(&self.message)
+ fmt::Display::fmt(self, f)
+ }
+}
+
+impl From<io::Error> for PdfError {
+ #[inline]
+ fn from(err: io::Error) -> PdfError {
+ PdfError::Io(err)
+ }
+}
+
+impl From<FontError> for PdfError {
+ #[inline]
+ fn from(err: FontError) -> PdfError {
+ PdfError::Font(err)
}
}