iri_string/template/
error.rs1use core::fmt;
4
5#[cfg(feature = "std")]
6use std::error;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub(super) enum ErrorKind {
11    WriteFailed,
13    ExpressionNotClosed,
15    InvalidCharacter,
17    InvalidExpression,
19    InvalidPercentEncoding,
21    InvalidUtf8,
23    UnexpectedValueType,
25    UnsupportedOperator,
27}
28
29impl ErrorKind {
30    #[must_use]
32    fn as_str(self) -> &'static str {
33        match self {
34            Self::WriteFailed => "failed to write to the backend writer",
35            Self::ExpressionNotClosed => "expression not closed",
36            Self::InvalidCharacter => "invalid character",
37            Self::InvalidExpression => "invalid expression",
38            Self::InvalidPercentEncoding => "invalid percent-encoded triplets",
39            Self::InvalidUtf8 => "invalid utf-8 byte sequence",
40            Self::UnexpectedValueType => "unexpected value type for the variable",
41            Self::UnsupportedOperator => "unsupported operator",
42        }
43    }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub struct Error {
53    kind: ErrorKind,
55    location: usize,
57}
58
59impl Error {
60    #[inline]
64    #[must_use]
65    pub(super) fn new(kind: ErrorKind, location: usize) -> Self {
66        Self { kind, location }
67    }
68
69    #[cfg(test)]
75    pub(super) fn location(&self) -> usize {
76        self.location
77    }
78}
79
80impl fmt::Display for Error {
81    #[inline]
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        write!(
84            f,
85            "invalid URI template: {} (at {}-th byte)",
86            self.kind.as_str(),
87            self.location
88        )
89    }
90}
91
92#[cfg(feature = "std")]
93impl error::Error for Error {}
94
95#[cfg(feature = "alloc")]
98pub struct CreationError<T> {
99    source: T,
101    error: Error,
103}
104
105#[cfg(feature = "alloc")]
106impl<T> CreationError<T> {
107    #[must_use]
109    pub fn into_source(self) -> T {
110        self.source
111    }
112
113    #[must_use]
115    pub fn validation_error(&self) -> Error {
116        self.error
117    }
118
119    #[must_use]
121    pub(crate) fn new(error: Error, source: T) -> Self {
122        Self { source, error }
123    }
124}
125
126#[cfg(feature = "alloc")]
127impl<T: fmt::Debug> fmt::Debug for CreationError<T> {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        f.debug_struct("CreationError")
130            .field("source", &self.source)
131            .field("error", &self.error)
132            .finish()
133    }
134}
135
136#[cfg(feature = "alloc")]
137impl<T: Clone> Clone for CreationError<T> {
138    fn clone(&self) -> Self {
139        Self {
140            source: self.source.clone(),
141            error: self.error,
142        }
143    }
144}
145
146#[cfg(feature = "alloc")]
147impl<T> fmt::Display for CreationError<T> {
148    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149        self.error.fmt(f)
150    }
151}
152
153#[cfg(feature = "std")]
154impl<T: fmt::Debug> error::Error for CreationError<T> {}