rudis_http/command/
mod.rs1mod get;
2
3pub use get::Get;
4
5mod set;
6use httparse::Request;
7use serde_json::{Map, Result, Value};
8pub use set::{MultipleSet, Set};
9
10pub enum Command {
11 Set(Set),
12 Get(Get),
13 MultipleSet(MultipleSet),
14 Invalid,
15}
16
17#[derive(Debug)]
18struct Args {
19 valid: bool,
20 command: String,
21 key: String,
22 val: Option<String>,
23 kv: Option<Map<String, Value>>,
24}
25
26impl Args {
27 pub fn new_invalid(command_type: &str) -> Self {
28 Args {
29 valid: false,
30 command: String::from(command_type),
31 key: String::from(""),
32 val: None,
33 kv: None,
34 }
35 }
36}
37
38impl Command {
39 pub fn from_bytes(http_request_buff: &[u8]) -> Command {
40 if http_request_buff.len() == 0 {
41 return Command::Invalid;
42 }
43
44 let mut headers = [httparse::EMPTY_HEADER; 16];
45 let mut req = Request::new(&mut headers);
46 let result = req.parse(http_request_buff).unwrap();
47 let n = result.unwrap();
48
49 let arg = make_args(&req, http_request_buff, n);
50
51 match arg.command.as_str() {
52 "GET" => {
53 if arg.valid == false {
54 return Command::Get(Get::new_invalid());
55 }
56 Command::Get(Get::from_key(arg.key))
57 }
58 "SET" => {
59 if arg.valid == false {
60 return Command::Set(Set::new_invalid());
61 }
62 Command::Set(Set::from_key_val(arg.key, arg.val.unwrap()))
63 }
64 "MULTIPLE_SET" => {
65 if arg.valid == false {
66 return Command::MultipleSet(MultipleSet::new_invalid());
67 }
68 let json_kv = arg.kv.unwrap();
69 if let Some(arg) = MultipleSet::from_json_kv(json_kv) {
70 return Command::MultipleSet(arg);
71 } else {
72 return Command::MultipleSet(MultipleSet::new_invalid());
73 }
74 }
75 _ => Command::Invalid,
76 }
77 }
78}
79
80fn make_args(req: &Request, request_buff: &[u8], idx_of_body: usize) -> Args {
81 let method = req.method.unwrap();
82 let all_path_vec = split_on_path(req.path.unwrap());
83
84 if method == "GET" {
86 let action = all_path_vec[0];
87 match action.to_uppercase().as_str() {
88 "GET" => {
89 if all_path_vec.len() < 2 || all_path_vec[1].is_empty() || all_path_vec.len() > 2 {
90 return Args::new_invalid("GET");
91 }
92 let key = all_path_vec[1];
93 return Args {
94 valid: true,
95 command: String::from("GET"),
96 key: String::from(key),
97 val: None,
98 kv: None,
99 };
100 }
101 "SET" => {
102 if all_path_vec.len() < 3
103 || all_path_vec[1].is_empty()
104 || all_path_vec[2].is_empty()
105 || all_path_vec.len() > 3
106 {
107 return Args::new_invalid("SET");
108 }
109 let key = all_path_vec[1];
110 let val = all_path_vec[2];
111 return Args {
112 valid: true,
113 command: String::from("SET"),
114 key: String::from(key),
115 val: Some(String::from(val)),
116 kv: None,
117 };
118 }
119 _ => return Args::new_invalid("INVALID"),
120 }
121 } else if method == "POST" {
122 if all_path_vec.len() != 1 {
124 return Args::new_invalid("SET");
125 }
126 let body = request_buff[idx_of_body..].to_vec();
127 match parse_json(&body) {
128 Ok(value) => {
129 if let Some(obj) = value.as_object() {
130 return Args {
131 valid: true,
132 command: String::from("MULTIPLE_SET"),
133 key: String::from(""),
134 val: None,
135 kv: Some(obj.clone()),
136 };
137 }
138 return Args::new_invalid("SET");
139 }
140 Err(_) => return Args::new_invalid("SET"),
141 }
142 }
143 Args::new_invalid("INVALID")
144}
145
146fn split_on_path(input: &str) -> Vec<&str> {
147 let all: Vec<&str> = input.split("/").collect();
148 if let Some((_, rest)) = all.split_first() {
149 return rest.to_vec();
150 }
151 all
152}
153
154fn parse_json(bytes: &[u8]) -> Result<Value> {
155 let value = serde_json::from_slice(bytes)?;
156 Ok(value)
157}