1use std::{error, fmt};
7use std::convert::Infallible;
8use super::source::Pos;
9
10
11pub struct ContentError {
15 message: ErrorMessage,
17}
18
19impl ContentError {
20 pub fn from_static(msg: &'static str) -> Self {
22 ContentError {
23 message: ErrorMessage::Static(msg)
24 }
25 }
26
27 pub fn from_boxed(
29 msg: Box<dyn fmt::Display + Send + Sync + 'static>
30 ) -> Self {
31 ContentError {
32 message: ErrorMessage::Boxed(msg)
33 }
34 }
35}
36
37impl From<&'static str> for ContentError {
38 fn from(msg: &'static str) -> Self {
39 Self::from_static(msg)
40 }
41}
42
43impl From<String> for ContentError {
44 fn from(msg: String) -> Self {
45 Self::from_boxed(Box::new(msg))
46 }
47}
48
49impl From<DecodeError<Infallible>> for ContentError {
50 fn from(err: DecodeError<Infallible>) -> Self {
51 match err.inner {
52 DecodeErrorKind::Source(_) => unreachable!(),
53 DecodeErrorKind::Content { error, .. } => error,
54 }
55 }
56}
57
58
59impl fmt::Display for ContentError {
60 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
61 self.message.fmt(f)
62 }
63}
64
65impl fmt::Debug for ContentError {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 f.debug_tuple("ContentError")
68 .field(&self.message)
69 .finish()
70 }
71}
72
73
74enum ErrorMessage {
78 Static(&'static str),
80
81 Boxed(Box<dyn fmt::Display + Send + Sync + 'static>),
83}
84
85impl fmt::Display for ErrorMessage {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match self {
88 ErrorMessage::Static(msg) => f.write_str(msg),
89 ErrorMessage::Boxed(ref msg) => msg.fmt(f),
90 }
91 }
92}
93
94impl fmt::Debug for ErrorMessage {
95 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
96 match self {
97 ErrorMessage::Static(msg) => f.write_str(msg),
98 ErrorMessage::Boxed(ref msg) => msg.fmt(f),
99 }
100 }
101}
102
103
104#[derive(Debug)]
111pub struct DecodeError<S> {
112 inner: DecodeErrorKind<S>,
113}
114
115#[derive(Debug)]
116enum DecodeErrorKind<S> {
117 Source(S),
118 Content {
119 error: ContentError,
120 pos: Pos,
121 }
122}
123
124impl<S> DecodeError<S> {
125 pub fn content(error: impl Into<ContentError>, pos: Pos) -> Self {
127 DecodeError {
128 inner: DecodeErrorKind::Content { error: error.into(), pos },
129 }
130 }
131}
132
133impl DecodeError<Infallible> {
134 pub fn convert<S>(self) -> DecodeError<S> {
136 match self.inner {
137 DecodeErrorKind::Source(_) => unreachable!(),
138 DecodeErrorKind::Content { error, pos } => {
139 DecodeError::content(error, pos)
140 }
141 }
142 }
143}
144
145impl<S> From<S> for DecodeError<S> {
146 fn from(err: S) -> Self {
147 DecodeError { inner: DecodeErrorKind::Source(err) }
148 }
149}
150
151impl<S: fmt::Display> fmt::Display for DecodeError<S> {
152 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153 match self.inner {
154 DecodeErrorKind::Source(ref err) => err.fmt(f),
155 DecodeErrorKind::Content { ref error, pos } => {
156 write!(f, "{} (at position {})", error, pos)
157 }
158 }
159 }
160}
161
162impl<S: fmt::Display + fmt::Debug> error::Error for DecodeError<S> { }
163