Create error_type! macro ✔

This commit is contained in:
Laurenz 2019-03-30 16:42:52 +01:00
parent 10994ebac3
commit f683bba400
6 changed files with 106 additions and 196 deletions

View File

@ -1,8 +1,5 @@
//! Core typesetting engine.
use std::io;
use std::error;
use std::fmt;
use crate::syntax::{SyntaxTree, Node};
use crate::doc::{Document, Size, Page, Text, TextCommand};
use crate::font::{Font, FontConfig, FontError};
@ -141,58 +138,25 @@ impl<'a> Engine<'a> {
}
}
/// Result type used for typesetting.
type TypeResult<T> = std::result::Result<T, TypesetError>;
/// The error type for typesetting.
pub enum TypesetError {
/// There was no suitable font.
MissingFont,
/// An error occured while gathering font data.
Font(FontError),
/// An I/O Error on occured while reading a font.
Io(io::Error),
}
impl error::Error for TypesetError {
#[inline]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
TypesetError::Font(err) => Some(err),
TypesetError::Io(err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for TypesetError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
error_type! {
err: TypesetError,
res: TypeResult,
show: f => match err {
TypesetError::MissingFont => write!(f, "missing font"),
TypesetError::Font(err) => write!(f, "font error: {}", err),
TypesetError::Io(err) => write!(f, "io error: {}", err),
}
}
}
impl fmt::Debug for TypesetError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}
impl From<io::Error> for TypesetError {
#[inline]
fn from(err: io::Error) -> TypesetError {
TypesetError::Io(err)
}
}
impl From<FontError> for TypesetError {
#[inline]
fn from(err: FontError) -> TypesetError {
TypesetError::Font(err)
}
},
source: match err {
TypesetError::Font(err) => Some(err),
_ => None,
},
from: (std::io::Error, TypesetError::Font(FontError::Io(err))),
from: (FontError, TypesetError::Font(err)),
}

38
src/error.rs Normal file
View File

@ -0,0 +1,38 @@
/// Create an error type.
macro_rules! error_type {
(
$var:ident: $err:ident,
$(res: $res:ident,)*
show: $f:ident => $show:expr,
$(source: $source:expr,)*
$(from: ($from:path, $conv:expr),)*
) => {
$(type $res<T> = std::result::Result<T, $err>;)*
impl std::fmt::Display for $err {
fn fmt(&self, $f: &mut std::fmt::Formatter) -> std::fmt::Result {
let $var = self;
$show
}
}
impl std::fmt::Debug for $err {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(self, f)
}
}
impl std::error::Error for $err {
$(fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let $var = self;
$source
})*
}
$(impl From<$from> for $err {
fn from($var: $from) -> $err {
$conv
}
})*
};
}

View File

@ -1,14 +1,11 @@
//! Exporting into _PDF_ documents.
use std::collections::HashSet;
use std::fmt::{self, Display, Debug, Formatter};
use std::io::{self, Write};
use pdf::{PdfWriter, Ref, Rect, Version, Trailer, Content};
use pdf::doc::{Catalog, PageTree, Page, Resource, Text};
use pdf::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
use pdf::font::{GlyphUnit, CMapEncoding, WidthRecord, FontStream, EmbeddedFontType};
use crate::doc::{Document, Size, Text as DocText, TextCommand};
use crate::font::{Font, FontError};
@ -284,9 +281,6 @@ impl std::ops::Deref for PdfFont {
}
}
/// Result type for _PDF_ creation.
type PdfResult<T> = std::result::Result<T, PdfExportError>;
/// The error type for _PDF_ creation.
pub enum PdfExportError {
/// An error occured while subsetting the font for the _PDF_.
@ -295,38 +289,17 @@ pub enum PdfExportError {
Io(io::Error),
}
impl std::error::Error for PdfExportError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
PdfExportError::Font(err) => Some(err),
PdfExportError::Io(err) => Some(err),
}
}
}
impl Display for PdfExportError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
error_type! {
err: PdfExportError,
res: PdfResult,
show: f => match err {
PdfExportError::Font(err) => write!(f, "font error: {}", err),
PdfExportError::Io(err) => write!(f, "io error: {}", err),
}
}
}
impl Debug for PdfExportError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
impl From<io::Error> for PdfExportError {
fn from(err: io::Error) -> PdfExportError {
PdfExportError::Io(err)
}
}
impl From<FontError> for PdfExportError {
fn from(err: FontError) -> PdfExportError {
PdfExportError::Font(err)
}
},
source: match err {
PdfExportError::Font(err) => Some(err),
PdfExportError::Io(err) => Some(err),
},
from: (io::Error, PdfExportError::Io(err)),
from: (FontError, PdfExportError::Font(err)),
}

View File

@ -3,8 +3,6 @@
#![macro_use]
use std::collections::HashMap;
use std::error;
use std::fmt;
use std::path::{Path, PathBuf};
use std::io::{self, Cursor, Read, Seek, SeekFrom};
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
@ -715,8 +713,6 @@ impl FontProvider for FileFontProvider<'_> {
}
}
type FontResult<T> = Result<T, FontError>;
/// The error type for font operations.
pub enum FontError {
/// The font file is incorrect.
@ -731,50 +727,25 @@ pub enum FontError {
Io(io::Error),
}
impl error::Error for FontError {
#[inline]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
FontError::Io(err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for FontError {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
error_type! {
err: FontError,
res: FontResult,
show: f => match err {
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 {
FontError::Io(err)
}
}
impl From<OpentypeError> for FontError {
fn from(err: OpentypeError) -> FontError {
match err {
},
source: match err {
FontError::Io(err) => Some(err),
_ => None,
},
from: (io::Error, FontError::Io(err)),
from: (OpentypeError, match 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"),
}
}
}),
}

View File

@ -38,20 +38,21 @@
//! exporter.export(&document, &mut file).unwrap();
//! ```
use std::fmt::{self, Display, Debug, Formatter};
use crate::syntax::SyntaxTree;
use crate::parsing::{Tokens, Parser, ParseError};
use crate::doc::{Document, Style};
use crate::font::FontProvider;
use crate::engine::{Engine, TypesetError};
#[macro_use]
mod error;
mod utility;
pub mod doc;
pub mod engine;
pub mod export;
pub mod font;
pub mod parsing;
pub mod syntax;
mod utility;
/// Transforms source code into typesetted documents.
@ -120,43 +121,20 @@ pub enum Error {
Typeset(TypesetError),
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Parse(err) => Some(err),
Error::Typeset(err) => Some(err),
}
}
error_type! {
err: Error,
show: f => match err {
Error::Parse(e) => write!(f, "parse error: {}", e),
Error::Typeset(e) => write!(f, "typeset error: {}", e),
},
source: match err {
Error::Parse(e) => Some(e),
Error::Typeset(e) => Some(e),
},
from: (ParseError, Error::Parse(err)),
from: (TypesetError, Error::Typeset(err)),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Error::Parse(err) => write!(f, "parse error: {}", err),
Error::Typeset(err) => write!(f, "typeset error: {}", err),
}
}
}
impl Debug for Error {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(self, f)
}
}
impl From<ParseError> for Error {
fn from(err: ParseError) -> Error {
Error::Parse(err)
}
}
impl From<TypesetError> for Error {
fn from(err: TypesetError) -> Error {
Error::Typeset(err)
}
}
#[cfg(test)]
mod test {
use std::fs::File;

View File

@ -1,6 +1,5 @@
//! Parsing of source code into tokens and syntax trees.
use std::error;
use std::fmt;
use std::iter::Peekable;
use std::mem::swap;
@ -9,7 +8,7 @@ use crate::syntax::*;
use crate::utility::{Splinor, Spline, Splined, StrExt};
/// An iterator over the tokens of a text.
/// An iterator over the tokens of source code.
#[derive(Clone)]
pub struct Tokens<'s> {
source: &'s str,
@ -211,7 +210,7 @@ impl<'s> Tokens<'s> {
}
}
/// Parses a token stream into an abstract syntax tree.
/// Transforms token streams to syntax trees.
#[derive(Debug, Clone)]
pub struct Parser<'s, T> where T: Iterator<Item = Token<'s>> {
tokens: Peekable<T>,
@ -355,30 +354,17 @@ impl<'s, T> Parser<'s, T> where T: Iterator<Item = Token<'s>> {
}
}
/// Result type used for parsing.
type ParseResult<T> = std::result::Result<T, ParseError>;
/// The error type for parsing.
pub struct ParseError {
/// A message describing the error.
message: String,
}
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)
}
error_type! {
err: ParseError,
res: ParseResult,
show: f => f.write_str(&err.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 {