use std::fmt;
use std::str::FromStr;
use error::HttpError;
use self::Method::{Options, Get, Post, Put, Delete, Head, Trace, Connect, Patch,
Extension};
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum Method {
Options,
Get,
Post,
Put,
Delete,
Head,
Trace,
Connect,
Patch,
Extension(String)
}
impl Method {
pub fn safe(&self) -> bool {
match *self {
Get | Head | Options | Trace => true,
_ => false
}
}
pub fn idempotent(&self) -> bool {
if self.safe() {
true
} else {
match *self {
Put | Delete => true,
_ => false
}
}
}
}
impl FromStr for Method {
type Err = HttpError;
fn from_str(s: &str) -> Result<Method, HttpError> {
if s == "" {
Err(HttpError::HttpMethodError)
} else {
Ok(match s {
"OPTIONS" => Options,
"GET" => Get,
"POST" => Post,
"PUT" => Put,
"DELETE" => Delete,
"HEAD" => Head,
"TRACE" => Trace,
"CONNECT" => Connect,
"PATCH" => Patch,
_ => Extension(s.to_string())
})
}
}
}
impl fmt::Display for Method {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(match *self {
Options => "OPTIONS",
Get => "GET",
Post => "POST",
Put => "PUT",
Delete => "DELETE",
Head => "HEAD",
Trace => "TRACE",
Connect => "CONNECT",
Patch => "PATCH",
Extension(ref s) => s.as_slice()
})
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::str::FromStr;
use super::Method;
use super::Method::{Get, Post, Put, Extension};
#[test]
fn test_safe() {
assert_eq!(true, Get.safe());
assert_eq!(false, Post.safe());
}
#[test]
fn test_idempotent() {
assert_eq!(true, Get.idempotent());
assert_eq!(true, Put.idempotent());
assert_eq!(false, Post.idempotent());
}
#[test]
fn test_from_str() {
assert_eq!(Ok(Get), FromStr::from_str("GET"));
assert_eq!(Ok(Extension("MOVE".to_string())),
FromStr::from_str("MOVE"));
}
#[test]
fn test_fmt() {
assert_eq!("GET".to_string(), format!("{}", Get));
assert_eq!("MOVE".to_string(),
format!("{}", Extension("MOVE".to_string())));
}
#[test]
fn test_hashable() {
let mut counter: HashMap<Method,usize> = HashMap::new();
counter.insert(Get, 1);
assert_eq!(Some(&1), counter.get(&Get));
}
}