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