1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use std::error;
use std::fmt;
use std::result;

use url;

use header;
use method;
use request;
use status;

/// A generic "error" for HTTP connections
///
/// This error type is less specific than the error returned from other
/// functions in this crate, but all other errors can be converted to this
/// error. Consumers of this crate can typically consume and work with this form
/// of error for conversions with the `?` operator.
#[derive(Debug)]
pub struct Error {
    inner: ErrorKind,
}

/// A `Result` typedef to use with the `http::Error` type
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
enum ErrorKind {
    StatusCode(status::InvalidStatusCode),
    Method(method::InvalidMethod),
    Url(url::ParseError),
    BadTarget(request::BadTarget),
    HeaderName(header::InvalidHeaderName),
    HeaderNameShared(header::InvalidHeaderNameBytes),
    HeaderValue(header::InvalidHeaderValue),
    HeaderValueShared(header::InvalidHeaderValueBytes),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        error::Error::description(self).fmt(f)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        use self::ErrorKind::*;

        match self.inner {
            StatusCode(ref e) => e.description(),
            Method(ref e) => e.description(),
            Url(ref e) => e.description(),
            BadTarget(ref e) => e.description(),
            HeaderName(ref e) => e.description(),
            HeaderNameShared(ref e) => e.description(),
            HeaderValue(ref e) => e.description(),
            HeaderValueShared(ref e) => e.description(),
        }
    }
}

impl From<status::InvalidStatusCode> for Error {
    fn from(err: status::InvalidStatusCode) -> Error {
        Error { inner: ErrorKind::StatusCode(err) }
    }
}

impl From<method::InvalidMethod> for Error {
    fn from(err: method::InvalidMethod) -> Error {
        Error { inner: ErrorKind::Method(err) }
    }
}

impl From<url::ParseError> for Error {
    fn from(err: url::ParseError) -> Error {
        Error { inner: ErrorKind::Url(err) }
    }
}

impl From<request::BadTarget> for Error {
    fn from(err: request::BadTarget) -> Error {
        Error { inner: ErrorKind::BadTarget(err) }
    }
}

impl From<header::InvalidHeaderName> for Error {
    fn from(err: header::InvalidHeaderName) -> Error {
        Error { inner: ErrorKind::HeaderName(err) }
    }
}

impl From<header::InvalidHeaderNameBytes> for Error {
    fn from(err: header::InvalidHeaderNameBytes) -> Error {
        Error { inner: ErrorKind::HeaderNameShared(err) }
    }
}

impl From<header::InvalidHeaderValue> for Error {
    fn from(err: header::InvalidHeaderValue) -> Error {
        Error { inner: ErrorKind::HeaderValue(err) }
    }
}

impl From<header::InvalidHeaderValueBytes> for Error {
    fn from(err: header::InvalidHeaderValueBytes) -> Error {
        Error { inner: ErrorKind::HeaderValueShared(err) }
    }
}