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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// License: see LICENSE file at root directory of `master` branch

//! # Method

use {
    alloc::string::String,
    core::{
        convert::TryFrom,
        fmt::{self, Display, Formatter},
        str::FromStr,
    },
    crate::Error,
};

const METHOD_GET: &str = "GET";
const METHOD_HEAD: &str = "HEAD";
const METHOD_POST: &str = "POST";
const METHOD_PUT: &str = "PUT";
const METHOD_DELETE: &str = "DELETE";
const METHOD_CONNECT: &str = "CONNECT";
const METHOD_OPTIONS: &str = "OPTIONS";
const METHOD_TRACE: &str = "TRACE";
const METHOD_PATCH: &str = "PATCH";

/// # Method
///
/// ## References
///
/// - <https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods>
#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub enum Method {

    /// # Get
    Get,

    /// # Head
    Head,

    /// # Post
    Post,

    /// # Put
    Put,

    /// # Delete
    Delete,

    /// # Connect
    Connect,

    /// # Options
    Options,

    /// # Trace
    Trace,

    /// # Patch
    Patch,

}

impl Display for Method {

    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        f.write_str(match self {
            Method::Get => METHOD_GET,
            Method::Head => METHOD_HEAD,
            Method::Post => METHOD_POST,
            Method::Put => METHOD_PUT,
            Method::Delete => METHOD_DELETE,
            Method::Connect => METHOD_CONNECT,
            Method::Options => METHOD_OPTIONS,
            Method::Trace => METHOD_TRACE,
            Method::Patch => METHOD_PATCH,
        })
    }

}

impl FromStr for Method {

    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            METHOD_GET => Ok(Method::Get),
            METHOD_HEAD => Ok(Method::Head),
            METHOD_POST => Ok(Method::Post),
            METHOD_PUT => Ok(Method::Put),
            METHOD_DELETE => Ok(Method::Delete),
            METHOD_CONNECT => Ok(Method::Connect),
            METHOD_OPTIONS => Ok(Method::Options),
            METHOD_TRACE => Ok(Method::Trace),
            METHOD_PATCH => Ok(Method::Patch),
            _ => Err(e!("Unknown method: {}", s)),
        }
    }

}

impl TryFrom<&[u8]> for Method {

    type Error = Error;

    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
        if METHOD_GET.as_bytes() == bytes {
            return Ok(Method::Get);
        }
        if METHOD_HEAD.as_bytes() == bytes {
            return Ok(Method::Head);
        }
        if METHOD_POST.as_bytes() == bytes {
            return Ok(Method::Post);
        }
        if METHOD_PUT.as_bytes() == bytes {
            return Ok(Method::Put);
        }
        if METHOD_DELETE.as_bytes() == bytes {
            return Ok(Method::Delete);
        }
        if METHOD_CONNECT.as_bytes() == bytes {
            return Ok(Method::Connect);
        }
        if METHOD_OPTIONS.as_bytes() == bytes {
            return Ok(Method::Options);
        }
        if METHOD_TRACE.as_bytes() == bytes {
            return Ok(Method::Trace);
        }
        if METHOD_PATCH.as_bytes() == bytes {
            return Ok(Method::Patch);
        }

        Err(e!("Unknown method: {:?}...", String::from_utf8_lossy(&bytes[..bytes.len().min(20)])))
    }

}