1use std::borrow::Cow;
2use hyper::status::StatusCode;
3use std::io;
4use std::error::Error;
5use response::Response;
6use hyper::net::{Fresh, Streaming};
7
8pub struct NickelError<'a, D: 'a = ()> {
11 pub stream: Option<Response<'a, D, Streaming>>,
12 pub message: Cow<'static, str>
13}
14
15impl<'a, D> NickelError<'a, D> {
16 pub fn new<T>(mut stream: Response<'a, D, Fresh>,
35 message: T,
36 status_code: StatusCode) -> NickelError<'a, D>
37 where T: Into<Cow<'static, str>> {
38 stream.set(status_code);
39
40 match stream.start() {
41 Ok(stream) =>
42 NickelError {
43 stream: Some(stream),
44 message: message.into(),
45 },
46 Err(e) => e
47 }
48 }
49
50 pub unsafe fn without_response<T>(message: T) -> NickelError<'a, D>
60 where T: Into<Cow<'static, str>> {
61 NickelError {
62 stream: None,
63 message: message.into(),
64 }
65 }
66
67 pub fn end(self) -> Option<io::Result<()>> {
68 self.stream.map(|s| s.end())
69 }
70}
71
72impl<'a, T, D> From<(Response<'a, D>, (StatusCode, T))> for NickelError<'a, D>
73 where T: Into<Box<Error + 'static>> {
74 fn from((res, (errorcode, err)): (Response<'a, D>, (StatusCode, T))) -> NickelError<'a, D> {
75 let err = err.into();
76 NickelError::new(res, err.description().to_string(), errorcode)
77 }
78}
79
80impl<'a, D> From<(Response<'a, D>, String)> for NickelError<'a, D> {
81 fn from((res, msg): (Response<'a, D>, String)) -> NickelError<'a, D> {
82 NickelError::new(res, msg, StatusCode::InternalServerError)
83 }
84}
85
86impl<'a, D> From<(Response<'a, D>, StatusCode)> for NickelError<'a, D> {
87 fn from((res, code): (Response<'a, D>, StatusCode)) -> NickelError<'a, D> {
88 NickelError::new(res, "", code)
89 }
90}