1 | // Copyright 2018 the SVG Types Authors |
2 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
3 | |
4 | /// List of all errors. |
5 | #[derive (Debug, PartialEq, Eq)] |
6 | pub enum Error { |
7 | /// An input data ended earlier than expected. |
8 | /// |
9 | /// Should only appear on invalid input data. |
10 | /// Errors in a valid XML should be handled by errors below. |
11 | UnexpectedEndOfStream, |
12 | |
13 | /// An input text contains unknown data. |
14 | UnexpectedData(usize), |
15 | |
16 | /// A provided string doesn't have a valid data. |
17 | /// |
18 | /// For example, if we try to parse a color form `zzz` |
19 | /// string - we will get this error. |
20 | /// But if we try to parse a number list like `1.2 zzz`, |
21 | /// then we will get `InvalidNumber`, because at least some data is valid. |
22 | InvalidValue, |
23 | |
24 | /// An invalid ident. |
25 | /// |
26 | /// CSS idents have certain rules with regard to the characters they may contain. |
27 | /// For example, they may not start with a number. If an invalid ident is encountered, |
28 | /// this error will be returned. |
29 | InvalidIdent, |
30 | |
31 | /// An invalid/unexpected character. |
32 | /// |
33 | /// The first byte is an actual one, others - expected. |
34 | /// |
35 | /// We are using a single value to reduce the struct size. |
36 | InvalidChar(Vec<u8>, usize), |
37 | |
38 | /// An unexpected character instead of an XML space. |
39 | /// |
40 | /// The first string is an actual one, others - expected. |
41 | /// |
42 | /// We are using a single value to reduce the struct size. |
43 | InvalidString(Vec<String>, usize), |
44 | |
45 | /// An invalid number. |
46 | InvalidNumber(usize), |
47 | } |
48 | |
49 | impl std::fmt::Display for Error { |
50 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
51 | match *self { |
52 | Error::UnexpectedEndOfStream => { |
53 | write!(f, "unexpected end of stream" ) |
54 | } |
55 | Error::UnexpectedData(pos) => { |
56 | write!(f, "unexpected data at position {}" , pos) |
57 | } |
58 | Error::InvalidValue => { |
59 | write!(f, "invalid value" ) |
60 | } |
61 | Error::InvalidIdent => { |
62 | write!(f, "invalid ident" ) |
63 | } |
64 | Error::InvalidChar(ref chars, pos) => { |
65 | // Vec<u8> -> Vec<String> |
66 | let list: Vec<String> = chars |
67 | .iter() |
68 | .skip(1) |
69 | .map(|c| String::from_utf8(vec![*c]).unwrap()) |
70 | .collect(); |
71 | |
72 | write!( |
73 | f, |
74 | "expected ' {}' not ' {}' at position {}" , |
75 | list.join("', '" ), |
76 | chars[0] as char, |
77 | pos |
78 | ) |
79 | } |
80 | Error::InvalidString(ref strings, pos) => { |
81 | write!( |
82 | f, |
83 | "expected ' {}' not ' {}' at position {}" , |
84 | strings[1..].join("', '" ), |
85 | strings[0], |
86 | pos |
87 | ) |
88 | } |
89 | Error::InvalidNumber(pos) => { |
90 | write!(f, "invalid number at position {}" , pos) |
91 | } |
92 | } |
93 | } |
94 | } |
95 | |
96 | impl std::error::Error for Error { |
97 | fn description(&self) -> &str { |
98 | "an SVG data parsing error" |
99 | } |
100 | } |
101 | |