1use std::fmt::{self, Display};
3
4use failure::{Fail, Context, Error as FError, Backtrace};
5
6use ::name::HeaderName;
7
8#[derive(Debug, Fail)]
11#[fail(display = "cast error caused by mixing different header implementations for {}", header_name)]
12pub struct HeaderTypeError {
13 header_name: HeaderName,
14 backtrace: Backtrace
15}
16
17impl HeaderTypeError {
18 pub fn new(name: HeaderName) -> Self {
19 HeaderTypeError {
20 header_name: name,
21 backtrace: Backtrace::new()
22 }
23 }
24
25 pub fn new_with_backtrace(name: HeaderName, backtrace: Backtrace) -> Self {
26 HeaderTypeError {
27 header_name: name,
28 backtrace
29 }
30 }
31}
32
33#[derive(Debug, Fail)]
39pub enum HeaderValidationError {
40 #[fail(display = "{}", _0)]
41 BuildIn(Context<BuildInValidationError>),
42 #[fail(display = "{}", _0)]
43 Custom(FError)
44}
45
46impl From<BuildInValidationError> for HeaderValidationError {
47 fn from(err: BuildInValidationError) -> Self {
48 HeaderValidationError::BuildIn(Context::new(err))
49 }
50}
51
52impl From<Context<BuildInValidationError>> for HeaderValidationError {
53 fn from(err: Context<BuildInValidationError>) -> Self {
54 HeaderValidationError::BuildIn(err)
55 }
56}
57
58#[derive(Copy, Clone, Debug, Fail, PartialEq, Eq, Hash)]
61pub enum BuildInValidationError {
62
63 #[fail(display = "{} header field contained both \"multi\" and \"max one\" header impl", header_name)]
69 MaxOneInconsistency { header_name: &'static str },
70
71 #[fail(display = "{} header field can appear at most one time in a header map", header_name)]
72 MoreThenOne { header_name: &'static str },
73
74 #[fail(display = "From field contained multiple addresses but no Sender field was set")]
75 MultiMailboxFromWithoutSender,
76
77 #[fail(display = "each resent block must have a resent-date field")]
78 ResentDateFieldMissing,
79
80 #[fail(display = "Resent-From field in resent block without a Resent-Sender field")]
81 MultiMailboxResentFromWithoutResentSender
82}
83
84macro_rules! header_validation_bail {
85 (kind: $($tt:tt)*) => ({
86 let build_in = $crate::error::BuildInValidationError::$($tt)*;
87 return Err(HeaderValidationError::BuildIn(::failure::Context::new(build_in)));
88 });
89}
90
91
92#[derive(Debug)]
98pub enum ChainTail {
99 Backtrace(Backtrace),
100 Error(FError)
101}
102
103impl ChainTail {
104
105 fn backtrace(&self) -> &Backtrace {
106 match *self {
107 ChainTail::Backtrace(ref trace) => trace,
108 ChainTail::Error(ref error) => error.backtrace()
109 }
110 }
111
112 fn as_fail(&self) -> Option<&Fail> {
113 match *self {
114 ChainTail::Backtrace(_) => None,
115 ChainTail::Error(ref error) => Some(error.as_fail())
116 }
117 }
118}
119
120#[derive(Debug)]
126pub struct ComponentCreationError {
127 component: &'static str,
128 backtrace: ChainTail,
129 str_context: Option<String>
130}
131
132impl ComponentCreationError {
133
134 pub fn from_parent<P>(parent: P, component: &'static str) -> Self
138 where P: Into<FError>
139 {
140 ComponentCreationError {
141 component,
142 backtrace: ChainTail::Error(parent.into()),
143 str_context: None
144 }
145 }
146
147 pub fn new(component: &'static str) -> Self {
151 ComponentCreationError {
152 component,
153 backtrace: ChainTail::Backtrace(Backtrace::new()),
154 str_context: None
155 }
156 }
157
158 pub fn new_with_str<I>(component: &'static str, str_context: I) -> Self
165 where I: Into<String>
166 {
167 ComponentCreationError {
168 component,
169 backtrace: ChainTail::Backtrace(Backtrace::new()),
170 str_context: Some(str_context.into())
171 }
172 }
173
174 pub fn str_context(&self) -> Option<&str> {
175 self.str_context.as_ref().map(|s|&**s)
176 }
177
178 pub fn set_str_context<I>(&mut self, ctx: I)
179 where I: Into<String>
180 {
181 self.str_context = Some(ctx.into());
182 }
183
184 pub fn with_str_context<I>(mut self, ctx: I) -> Self
185 where I: Into<String>
186 {
187 self.set_str_context(ctx);
188 self
189 }
190}
191
192impl Fail for ComponentCreationError {
193 fn cause(&self) -> Option<&Fail> {
194 self.backtrace.as_fail()
195 }
196 fn backtrace(&self) -> Option<&Backtrace> {
197 Some(self.backtrace.backtrace())
198 }
199}
200
201impl Display for ComponentCreationError {
202 fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
203 write!(fter, "creating component {} failed", self.component)
204 }
205}