1use crate::Method;
2
3use serde::{Deserialize, Serialize};
4
5use std::fs::File;
6use std::io::{BufReader, Write};
7use std::path::Path;
8
9#[derive(Serialize, Deserialize, Debug)]
10pub struct KeyValuePair {
11 pub key: String,
12 pub value: String,
13}
14
15impl KeyValuePair {
16 pub fn to_string(&self) -> String {
17 format!("{:}:{:}", self.key, self.value)
18 }
19}
20
21#[derive(Serialize, Deserialize, Debug)]
22pub struct Request {
23 pub key: String,
24 pub method: Method,
25 pub url: String,
26 #[serde(skip_serializing_if = "Option::is_none")]
30 pub headers: Option<Vec<KeyValuePair>>,
31 pub body: Option<String>,
32}
33
34impl Request {
35 pub fn headers_to_string(&self) -> String {
36 match &self.headers {
37 None => "".to_string(),
38 Some(headers) => {
39 let strings: Vec<String> = headers.iter().map(|i| i.to_string()).collect();
40 strings.join("\r\n")
41 }
42 }
43 }
44}
45
46pub struct RequestBuilder {
47 key: String,
48 method: Method,
49 url: Option<String>,
50 body: Option<String>,
51 headers: Option<String>,
52}
53
54impl RequestBuilder {
55 pub fn new(req_key: &str) -> RequestBuilder {
56 RequestBuilder {
57 key: req_key.to_string(),
58 method: Method::GET,
59 url: None,
60 headers: None,
61 body: None,
62 }
63 }
64
65 pub fn headers(&mut self, headers: &str) -> &Self {
66 self.headers = Some(headers.to_string());
67 self
68 }
69
70 pub fn url(&mut self, url: &str) -> &Self {
71 self.url = Some(url.to_string());
72 self
73 }
74
75 pub fn method(&mut self, method: Method) -> &Self {
76 self.method = method;
77 self
78 }
79
80 pub fn body(&mut self, body: &str) -> &Self {
81 self.body = Some(body.to_string());
82 self
83 }
84
85 pub fn build(self) -> Request {
86 let headers = match self.headers {
87 None => None,
88 Some(header_string) => {
89 let headers_strings: Vec<&str> = header_string.split("\r\n").collect();
90 let mut parsed_headers: Vec<KeyValuePair> = Vec::new();
91
92 for entry in headers_strings {
93 if let Some((key, value)) = entry.split_once(":") {
94 parsed_headers.push(KeyValuePair {
95 key: key.trim().to_string(),
96 value: value.trim().to_string(),
97 })
98 }
99 }
100 if parsed_headers.is_empty() {
101 None
102 } else {
103 Some(parsed_headers)
104 }
105 }
106 };
107
108 Request {
109 key: self.key,
110 method: self.method,
111 url: self.url.expect("Must set URL."),
112 headers,
113 body: self.body,
114 }
115 }
116}
117
118#[derive(Serialize, Deserialize, Debug)]
119pub struct RequestCollection {
120 pub requests: Vec<Request>,
121}
122
123impl RequestCollection {
124 pub fn new() -> Self {
125 RequestCollection {
126 requests: Vec::new(),
127 }
128 }
129
130 pub fn add_request(&mut self, request: Request) {
131 let req_key = request.key.as_str();
132 match self.requests.iter().position(|item| item.key == req_key) {
133 None => {
134 self.requests.push(request);
135 }
136 Some(index) => {
137 let _ = std::mem::replace(&mut self.requests[index], request);
138 }
139 };
140 }
141
142 pub fn remove_request(&mut self, index: usize) {
143 if index < self.requests.len() {
144 self.requests.remove(index);
145 }
146 }
147
148 pub fn save(&self) {
149 let serialized = serde_json::to_string_pretty(&self.requests);
150 info!("Serialized: {:?}", serialized);
151 let file = File::create("requests.json");
152 if let Ok(mut file) = file {
153 if let Err(err) = file.write_all(serialized.unwrap().as_bytes()) {
154 error!("Error writing file {:?}", err);
155 }
156 }
157 }
158
159 pub fn load() -> Self {
160 if Path::new("requests.json").exists() {
161 match File::open("requests.json") {
162 Ok(file) => {
163 let reader = BufReader::new(file);
164
165 match serde_json::from_reader(reader) {
167 Ok(collection) => {
168 return Self {
169 requests: collection,
170 };
171 }
172 _ => {}
173 }
174 }
175 Err(_) => {}
176 }
177 }
178 Self::new()
179 }
180}