1use strum::{AsRefStr, Display, EnumIter, EnumString};
2#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, EnumIter)]
21#[strum(ascii_case_insensitive, serialize_all = "UPPERCASE")]
22pub enum Method {
23 Options,
24 #[default]
25 Get,
26 Post,
27 Put,
28 Delete,
29 Head,
30 Trace,
31 Connect,
32 Patch,
33}
34
35impl Method {
36 pub fn is_safe(&self) -> bool {
42 use Method::*;
43 matches!(self, Get | Head | Options | Trace)
44 }
45
46 pub fn is_idempotent(&self) -> bool {
52 use Method::*;
53 match self {
54 Put | Delete => true,
55 _ => self.is_safe(),
56 }
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use core::str::FromStr;
63
64 use strum::IntoEnumIterator;
65
66 use super::*;
67
68 #[test]
69 fn test_enum_string() {
70 for method in Method::iter() {
71 let str = method.as_ref();
72 assert_eq!(Method::from_str(str).unwrap(), method);
73 }
74 }
75
76 #[test]
77 fn test_is_idempotent() {
78 assert!(Method::Options.is_idempotent());
79 assert!(Method::Get.is_idempotent());
80 assert!(Method::Put.is_idempotent());
81 assert!(Method::Delete.is_idempotent());
82 assert!(Method::Head.is_idempotent());
83 assert!(Method::Trace.is_idempotent());
84
85 assert!(!Method::Post.is_idempotent());
86 assert!(!Method::Connect.is_idempotent());
87 assert!(!Method::Patch.is_idempotent());
88 }
89}