diff --git a/src/engine.rs b/src/engine.rs index 2fbb830bb..5a6e27b06 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -132,15 +132,20 @@ impl<'s> Engine<'s> { type TypeResult = std::result::Result; /// 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 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&self.message) + #[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 { + fmt::Display::fmt(self, f) } } diff --git a/src/font.rs b/src/font.rs index ea59bd38c..40fa21026 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 TakeInvalid for Option { type FontResult = Result; -/// 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 for FontError { #[inline] fn from(err: io::Error) -> FontError { @@ -638,13 +639,12 @@ impl From for FontError { } } -impl From for FontError { - fn from(err: opentype::Error) -> FontError { - use opentype::Error::*; +impl From 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 29daa8537..6f2aaa538 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, Error> { - Parser::new(self.tokenize(source)).parse().map_err(Into::into) + pub fn parse<'s>(&self, source: &'s str) -> Result, 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 for Error { #[inline] fn from(err: ParseError) -> Error { @@ -140,10 +146,10 @@ impl From for Error { } } -impl From for Error { +impl From 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 37c83b3ff..5122597f9 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -359,7 +359,6 @@ impl<'s, T> Parser<'s, T> where T: Iterator> { type ParseResult = std::result::Result; /// 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 4cd78d0ae..b188ab91c 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 = std::result::Result; +type PdfResult = std::result::Result; /// 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 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 for PdfWritingError { - #[inline] - fn from(err: crate::font::FontError) -> PdfWritingError { - PdfWritingError { message: format!("{}", err) } - } -} - -impl fmt::Display for PdfWritingError { +impl fmt::Display for PdfError { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(&self.message) + match self { + PdfError::Font(err) => write!(f, "font error: {}", err), + PdfError::Io(err) => write!(f, "io error: {}", err), + } + } +} + +impl fmt::Debug for PdfError { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl From for PdfError { + #[inline] + fn from(err: io::Error) -> PdfError { + PdfError::Io(err) + } +} + +impl From for PdfError { + #[inline] + fn from(err: FontError) -> PdfError { + PdfError::Font(err) } }