1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "UPPERCASE")]
9pub enum HttpMethod {
10 Get,
11 Post,
12 Put,
13 Patch,
14 Delete,
15 Head,
16 Options,
17}
18
19impl HttpMethod {
20 #[must_use]
24 pub fn is_safe(&self) -> bool {
25 matches!(self, Self::Get | Self::Head | Self::Options)
26 }
27
28 #[must_use]
30 pub fn requires_capability(&self) -> bool {
31 !self.is_safe()
32 }
33}
34
35impl std::fmt::Display for HttpMethod {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 match self {
38 Self::Get => write!(f, "GET"),
39 Self::Post => write!(f, "POST"),
40 Self::Put => write!(f, "PUT"),
41 Self::Patch => write!(f, "PATCH"),
42 Self::Delete => write!(f, "DELETE"),
43 Self::Head => write!(f, "HEAD"),
44 Self::Options => write!(f, "OPTIONS"),
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn safe_methods() {
55 assert!(HttpMethod::Get.is_safe());
56 assert!(HttpMethod::Head.is_safe());
57 assert!(HttpMethod::Options.is_safe());
58 }
59
60 #[test]
61 fn unsafe_methods_require_capability() {
62 assert!(HttpMethod::Post.requires_capability());
63 assert!(HttpMethod::Put.requires_capability());
64 assert!(HttpMethod::Patch.requires_capability());
65 assert!(HttpMethod::Delete.requires_capability());
66 }
67
68 #[test]
69 fn display_uppercase() {
70 assert_eq!(HttpMethod::Get.to_string(), "GET");
71 assert_eq!(HttpMethod::Delete.to_string(), "DELETE");
72 }
73
74 #[test]
75 fn serde_roundtrip() {
76 let method = HttpMethod::Post;
77 let json = serde_json::to_string(&method).unwrap();
78 assert_eq!(json, "\"POST\"");
79 let back: HttpMethod = serde_json::from_str(&json).unwrap();
80 assert_eq!(back, method);
81 }
82}