mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Create error_type! macro ✔
This commit is contained in:
parent
10994ebac3
commit
f683bba400
@ -1,8 +1,5 @@
|
|||||||
//! Core typesetting engine.
|
//! Core typesetting engine.
|
||||||
|
|
||||||
use std::io;
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
use crate::syntax::{SyntaxTree, Node};
|
use crate::syntax::{SyntaxTree, Node};
|
||||||
use crate::doc::{Document, Size, Page, Text, TextCommand};
|
use crate::doc::{Document, Size, Page, Text, TextCommand};
|
||||||
use crate::font::{Font, FontConfig, FontError};
|
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.
|
/// The error type for typesetting.
|
||||||
pub enum TypesetError {
|
pub enum TypesetError {
|
||||||
/// There was no suitable font.
|
/// There was no suitable font.
|
||||||
MissingFont,
|
MissingFont,
|
||||||
/// An error occured while gathering font data.
|
/// An error occured while gathering font data.
|
||||||
Font(FontError),
|
Font(FontError),
|
||||||
/// An I/O Error on occured while reading a font.
|
|
||||||
Io(io::Error),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for TypesetError {
|
error_type! {
|
||||||
#[inline]
|
err: TypesetError,
|
||||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
res: TypeResult,
|
||||||
match self {
|
show: f => match err {
|
||||||
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 {
|
|
||||||
TypesetError::MissingFont => write!(f, "missing font"),
|
TypesetError::MissingFont => write!(f, "missing font"),
|
||||||
TypesetError::Font(err) => write!(f, "font error: {}", err),
|
TypesetError::Font(err) => write!(f, "font error: {}", err),
|
||||||
TypesetError::Io(err) => write!(f, "io error: {}", err),
|
},
|
||||||
}
|
source: match err {
|
||||||
}
|
TypesetError::Font(err) => Some(err),
|
||||||
}
|
_ => None,
|
||||||
|
},
|
||||||
impl fmt::Debug for TypesetError {
|
from: (std::io::Error, TypesetError::Font(FontError::Io(err))),
|
||||||
#[inline]
|
from: (FontError, TypesetError::Font(err)),
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
38
src/error.rs
Normal file
38
src/error.rs
Normal 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
|
||||||
|
}
|
||||||
|
})*
|
||||||
|
};
|
||||||
|
}
|
@ -1,14 +1,11 @@
|
|||||||
//! Exporting into _PDF_ documents.
|
//! Exporting into _PDF_ documents.
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{self, Display, Debug, Formatter};
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
use pdf::{PdfWriter, Ref, Rect, Version, Trailer, Content};
|
use pdf::{PdfWriter, Ref, Rect, Version, Trailer, Content};
|
||||||
use pdf::doc::{Catalog, PageTree, Page, Resource, Text};
|
use pdf::doc::{Catalog, PageTree, Page, Resource, Text};
|
||||||
use pdf::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
|
use pdf::font::{Type0Font, CIDFont, CIDFontType, CIDSystemInfo, FontDescriptor, FontFlags};
|
||||||
use pdf::font::{GlyphUnit, CMapEncoding, WidthRecord, FontStream, EmbeddedFontType};
|
use pdf::font::{GlyphUnit, CMapEncoding, WidthRecord, FontStream, EmbeddedFontType};
|
||||||
|
|
||||||
use crate::doc::{Document, Size, Text as DocText, TextCommand};
|
use crate::doc::{Document, Size, Text as DocText, TextCommand};
|
||||||
use crate::font::{Font, FontError};
|
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.
|
/// The error type for _PDF_ creation.
|
||||||
pub enum PdfExportError {
|
pub enum PdfExportError {
|
||||||
/// An error occured while subsetting the font for the _PDF_.
|
/// An error occured while subsetting the font for the _PDF_.
|
||||||
@ -295,38 +289,17 @@ pub enum PdfExportError {
|
|||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for PdfExportError {
|
error_type! {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
err: PdfExportError,
|
||||||
match self {
|
res: PdfResult,
|
||||||
PdfExportError::Font(err) => Some(err),
|
show: f => match err {
|
||||||
PdfExportError::Io(err) => Some(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for PdfExportError {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
PdfExportError::Font(err) => write!(f, "font error: {}", err),
|
PdfExportError::Font(err) => write!(f, "font error: {}", err),
|
||||||
PdfExportError::Io(err) => write!(f, "io error: {}", err),
|
PdfExportError::Io(err) => write!(f, "io error: {}", err),
|
||||||
}
|
},
|
||||||
}
|
source: match err {
|
||||||
}
|
PdfExportError::Font(err) => Some(err),
|
||||||
|
PdfExportError::Io(err) => Some(err),
|
||||||
impl Debug for PdfExportError {
|
},
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
from: (io::Error, PdfExportError::Io(err)),
|
||||||
Display::fmt(self, f)
|
from: (FontError, PdfExportError::Font(err)),
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
53
src/font.rs
53
src/font.rs
@ -3,8 +3,6 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::io::{self, Cursor, Read, Seek, SeekFrom};
|
use std::io::{self, Cursor, Read, Seek, SeekFrom};
|
||||||
use byteorder::{BE, ReadBytesExt, WriteBytesExt};
|
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.
|
/// The error type for font operations.
|
||||||
pub enum FontError {
|
pub enum FontError {
|
||||||
/// The font file is incorrect.
|
/// The font file is incorrect.
|
||||||
@ -731,50 +727,25 @@ pub enum FontError {
|
|||||||
Io(io::Error),
|
Io(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for FontError {
|
error_type! {
|
||||||
#[inline]
|
err: FontError,
|
||||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
res: FontResult,
|
||||||
match self {
|
show: f => match err {
|
||||||
FontError::Io(err) => Some(err),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for FontError {
|
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
FontError::InvalidFont(message) => write!(f, "invalid font: {}", message),
|
FontError::InvalidFont(message) => write!(f, "invalid font: {}", message),
|
||||||
FontError::MissingTable(table) => write!(f, "missing table: {}", table),
|
FontError::MissingTable(table) => write!(f, "missing table: {}", table),
|
||||||
FontError::UnsupportedTable(table) => write!(f, "unsupported table: {}", table),
|
FontError::UnsupportedTable(table) => write!(f, "unsupported table: {}", table),
|
||||||
FontError::MissingCharacter(c) => write!(f, "missing character: '{}'", c),
|
FontError::MissingCharacter(c) => write!(f, "missing character: '{}'", c),
|
||||||
FontError::Io(err) => write!(f, "io error: {}", err),
|
FontError::Io(err) => write!(f, "io error: {}", err),
|
||||||
}
|
},
|
||||||
}
|
source: match err {
|
||||||
}
|
FontError::Io(err) => Some(err),
|
||||||
|
_ => None,
|
||||||
impl fmt::Debug for FontError {
|
},
|
||||||
#[inline]
|
from: (io::Error, FontError::Io(err)),
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
from: (OpentypeError, match err {
|
||||||
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 {
|
|
||||||
OpentypeError::InvalidFont(message) => FontError::InvalidFont(message),
|
OpentypeError::InvalidFont(message) => FontError::InvalidFont(message),
|
||||||
OpentypeError::MissingTable(tag) => FontError::MissingTable(tag.to_string()),
|
OpentypeError::MissingTable(tag) => FontError::MissingTable(tag.to_string()),
|
||||||
OpentypeError::Io(err) => FontError::Io(err),
|
OpentypeError::Io(err) => FontError::Io(err),
|
||||||
_ => panic!("unexpected extensible variant"),
|
_ => panic!("unexpected extensible variant"),
|
||||||
}
|
}),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
52
src/lib.rs
52
src/lib.rs
@ -38,20 +38,21 @@
|
|||||||
//! exporter.export(&document, &mut file).unwrap();
|
//! exporter.export(&document, &mut file).unwrap();
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::fmt::{self, Display, Debug, Formatter};
|
|
||||||
use crate::syntax::SyntaxTree;
|
use crate::syntax::SyntaxTree;
|
||||||
use crate::parsing::{Tokens, Parser, ParseError};
|
use crate::parsing::{Tokens, Parser, ParseError};
|
||||||
use crate::doc::{Document, Style};
|
use crate::doc::{Document, Style};
|
||||||
use crate::font::FontProvider;
|
use crate::font::FontProvider;
|
||||||
use crate::engine::{Engine, TypesetError};
|
use crate::engine::{Engine, TypesetError};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
mod error;
|
||||||
|
mod utility;
|
||||||
pub mod doc;
|
pub mod doc;
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod export;
|
pub mod export;
|
||||||
pub mod font;
|
pub mod font;
|
||||||
pub mod parsing;
|
pub mod parsing;
|
||||||
pub mod syntax;
|
pub mod syntax;
|
||||||
mod utility;
|
|
||||||
|
|
||||||
|
|
||||||
/// Transforms source code into typesetted documents.
|
/// Transforms source code into typesetted documents.
|
||||||
@ -120,42 +121,19 @@ pub enum Error {
|
|||||||
Typeset(TypesetError),
|
Typeset(TypesetError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {
|
error_type! {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
err: Error,
|
||||||
match self {
|
show: f => match err {
|
||||||
Error::Parse(err) => Some(err),
|
Error::Parse(e) => write!(f, "parse error: {}", e),
|
||||||
Error::Typeset(err) => Some(err),
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//! Parsing of source code into tokens and syntax trees.
|
//! Parsing of source code into tokens and syntax trees.
|
||||||
|
|
||||||
use std::error;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::Peekable;
|
use std::iter::Peekable;
|
||||||
use std::mem::swap;
|
use std::mem::swap;
|
||||||
@ -9,7 +8,7 @@ use crate::syntax::*;
|
|||||||
use crate::utility::{Splinor, Spline, Splined, StrExt};
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct Tokens<'s> {
|
pub struct Tokens<'s> {
|
||||||
source: &'s str,
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Parser<'s, T> where T: Iterator<Item = Token<'s>> {
|
pub struct Parser<'s, T> where T: Iterator<Item = Token<'s>> {
|
||||||
tokens: Peekable<T>,
|
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.
|
/// The error type for parsing.
|
||||||
pub struct ParseError {
|
pub struct ParseError {
|
||||||
/// A message describing the error.
|
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl error::Error for ParseError {}
|
error_type! {
|
||||||
|
err: ParseError,
|
||||||
impl fmt::Display for ParseError {
|
res: ParseResult,
|
||||||
#[inline]
|
show: f => f.write_str(&err.message),
|
||||||
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)]
|
#[cfg(test)]
|
||||||
mod token_tests {
|
mod token_tests {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user