1
//! Error types
2

            
3
use crate::binary::read::ReadEof;
4
use crate::tag::DisplayTag;
5
use std::fmt;
6

            
7
/// Error returned from font shaping functions
8
#[derive(Clone, Eq, PartialEq, Debug)]
9
pub enum ShapingError {
10
    ComplexScript(ComplexScriptError),
11
    Parse(ParseError),
12
}
13

            
14
impl From<ComplexScriptError> for ShapingError {
15
    fn from(error: ComplexScriptError) -> Self {
16
        ShapingError::ComplexScript(error)
17
    }
18
}
19

            
20
impl From<ParseError> for ShapingError {
21
    fn from(error: ParseError) -> Self {
22
        ShapingError::Parse(error)
23
    }
24
}
25

            
26
impl From<std::num::TryFromIntError> for ShapingError {
27
    fn from(_error: std::num::TryFromIntError) -> Self {
28
        ShapingError::Parse(ParseError::BadValue)
29
    }
30
}
31

            
32
impl fmt::Display for ShapingError {
33
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34
        match self {
35
            ShapingError::ComplexScript(err) => write!(f, "indic shaping: {}", err),
36
            ShapingError::Parse(err) => write!(f, "shaping parse: {}", err),
37
        }
38
    }
39
}
40

            
41
impl std::error::Error for ShapingError {}
42

            
43
/// Error returned from font shaping complex scripts
44
#[derive(Clone, Eq, PartialEq, Debug)]
45
pub enum ComplexScriptError {
46
    EmptyBuffer,
47
    MissingBaseConsonant,
48
    MissingDottedCircle,
49
    MissingTags,
50
    UnexpectedGlyphOrigin,
51
}
52

            
53
/// Errors that originate when parsing binary data
54
#[derive(Clone, Eq, PartialEq, Debug)]
55
pub enum ParseError {
56
    BadEof,
57
    BadValue,
58
    BadVersion,
59
    BadOffset,
60
    BadIndex,
61
    LimitExceeded,
62
    MissingValue,
63
    MissingTable(u32),
64
    CompressionError,
65
    UnsuitableCmap,
66
    NotImplemented,
67
}
68

            
69
impl From<ReadEof> for ParseError {
70
22410
    fn from(_error: ReadEof) -> Self {
71
22410
        ParseError::BadEof
72
22410
    }
73
}
74

            
75
impl From<std::num::TryFromIntError> for ParseError {
76
    fn from(_error: std::num::TryFromIntError) -> Self {
77
        ParseError::BadValue
78
    }
79
}
80

            
81
impl fmt::Display for ParseError {
82
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83
        match self {
84
            ParseError::BadEof => write!(f, "end of data reached unexpectedly"),
85
            ParseError::BadValue => write!(f, "invalid value"),
86
            ParseError::BadVersion => write!(f, "unexpected data version"),
87
            ParseError::BadOffset => write!(f, "invalid data offset"),
88
            ParseError::BadIndex => write!(f, "invalid data index"),
89
            ParseError::LimitExceeded => write!(f, "limit exceeded"),
90
            ParseError::MissingValue => write!(f, "an expected data value was missing"),
91
            ParseError::MissingTable(tag) => {
92
                write!(f, "font is missing '{}' table", DisplayTag(*tag))
93
            }
94
            ParseError::CompressionError => write!(f, "compression error"),
95
            ParseError::UnsuitableCmap => write!(f, "no suitable cmap subtable"),
96
            ParseError::NotImplemented => write!(f, "feature not implemented"),
97
        }
98
    }
99
}
100

            
101
impl std::error::Error for ParseError {}
102

            
103
impl fmt::Display for ComplexScriptError {
104
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105
        match self {
106
            ComplexScriptError::EmptyBuffer => write!(f, "empty buffer"),
107
            ComplexScriptError::MissingBaseConsonant => write!(f, "missing base consonant"),
108
            ComplexScriptError::MissingDottedCircle => write!(f, "missing dotted circle"),
109
            ComplexScriptError::MissingTags => write!(f, "missing tags"),
110
            ComplexScriptError::UnexpectedGlyphOrigin => write!(f, "unexpected glyph origin"),
111
        }
112
    }
113
}
114

            
115
impl std::error::Error for ComplexScriptError {}
116

            
117
/// Errors that originate when writing binary data
118
#[derive(Clone, Eq, PartialEq, Debug)]
119
pub enum WriteError {
120
    BadValue,
121
    NotImplemented,
122
    PlaceholderMismatch,
123
}
124

            
125
impl From<std::num::TryFromIntError> for WriteError {
126
    fn from(_error: std::num::TryFromIntError) -> Self {
127
        WriteError::BadValue
128
    }
129
}
130

            
131
impl fmt::Display for WriteError {
132
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133
        match self {
134
            WriteError::BadValue => write!(f, "write: bad value"),
135
            WriteError::NotImplemented => write!(f, "writing in this format is not implemented"),
136
            WriteError::PlaceholderMismatch => {
137
                write!(f, "data written to placeholder did not match expected size")
138
            }
139
        }
140
    }
141
}
142

            
143
impl std::error::Error for WriteError {}
144

            
145
/// Enum that can hold read (`ParseError`) and write errors
146
#[derive(Clone, Eq, PartialEq, Debug)]
147
pub enum ReadWriteError {
148
    Read(ParseError),
149
    Write(WriteError),
150
}
151

            
152
impl From<ParseError> for ReadWriteError {
153
    fn from(error: ParseError) -> Self {
154
        ReadWriteError::Read(error)
155
    }
156
}
157

            
158
impl From<WriteError> for ReadWriteError {
159
    fn from(error: WriteError) -> Self {
160
        ReadWriteError::Write(error)
161
    }
162
}
163

            
164
impl fmt::Display for ReadWriteError {
165
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166
        match self {
167
            ReadWriteError::Read(err) => write!(f, "read error: {}", err),
168
            ReadWriteError::Write(err) => write!(f, "write error: {}", err),
169
        }
170
    }
171
}
172

            
173
impl std::error::Error for ReadWriteError {}