svgtypes/
error.rs

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)]
6pub 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
49impl 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
96impl std::error::Error for Error {
97    fn description(&self) -> &str {
98        "an SVG data parsing error"
99    }
100}