use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Serialize, Deserialize)]
pub enum Message {
Request(Request),
Response(Response),
}
#[derive(Serialize, Deserialize)]
pub struct Response {
url: Option<String>,
method: Option<String>,
status: u32,
headers: HashMap<String, Value>,
body: Value,
}
impl Response {
pub fn builder() -> ResponseBuilder {
ResponseBuilder {
url: Some("".into()),
status: 200,
method: Some("GET".into()),
headers: HashMap::new(),
body: Value::Null,
}
}
pub fn url(&self) -> Option<String> {
self.url.clone()
}
pub fn method(&self) -> Option<String> {
self.url.clone()
}
pub fn headers(&self) -> HashMap<String, Value> {
self.headers.clone()
}
pub fn body(&self) -> Value {
self.body.clone()
}
pub fn status(&self) -> u32 {
self.status
}
pub fn id(&self) -> Option<&str> {
self.headers.get("id").and_then(|id| id.as_str())
}
}
pub struct ResponseBuilder {
url: Option<String>,
method: Option<String>,
status: u32,
headers: HashMap<String, Value>,
body: Value,
}
impl ResponseBuilder {
pub fn url<S: Into<String>>(&mut self, url: S) -> &mut Self {
self.url = Some(url.into());
self
}
pub fn status(&mut self, status: u32) -> &mut Self {
self.status = status;
self
}
pub fn method<S: Into<String>>(&mut self, method: S) -> &mut Self {
self.method = Some(method.into());
self
}
pub fn headers(&mut self, headers: HashMap<String, Value>) -> &mut Self {
self.headers = headers;
self
}
pub fn body(&mut self, body: Value) -> &mut Self {
self.body = body;
self
}
pub fn build(&self) -> Response {
Response {
url: self.url.clone(),
status: self.status.clone(),
method: self.method.clone(),
headers: self.headers.clone(),
body: self.body.clone(),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct Request {
url: String,
method: Option<String>,
headers: HashMap<String, Value>,
body: Value,
}
impl Request {
pub fn builder() -> RequestBuilder {
RequestBuilder {
url: "".into(),
method: "GET".into(),
headers: HashMap::new(),
body: Value::Null,
}
}
pub fn id(&self) -> Option<&str> {
self.headers.get("id").and_then(|id| id.as_str())
}
pub fn url(&self) -> &str {
&self.url
}
pub fn method(&self) -> &Option<String> {
&self.method
}
pub fn headers(&self) -> HashMap<String, Value> {
self.headers.clone()
}
pub fn body(&self) -> Value {
self.body.clone()
}
}
pub struct RequestBuilder {
url: String,
method: String,
headers: HashMap<String, Value>,
body: Value,
}
impl RequestBuilder {
pub fn url<S: Into<String>>(&mut self, url: S) -> &mut Self {
self.url = url.into();
self
}
pub fn method<S: Into<String>>(&mut self, method: S) -> &mut Self {
self.method = method.into();
self
}
pub fn headers(&mut self, headers: HashMap<String, Value>) -> &mut Self {
self.headers = headers;
self
}
pub fn cookies(&mut self, cookies: HashMap<String, String>) -> &mut Self {
let mut cookieList = Vec::new();
for (key, value) in cookies {
cookieList.push(format!("{}={}", key, value));
}
let cookieString = cookieList.iter().map(|cookie| String::from(cookie) + "; ").collect();
self.headers.insert("Cookie".into(), Value::String(cookieString));
self
}
pub fn body(&mut self, body: Value) -> &mut Self {
self.body = body;
self
}
pub fn id<S: Into<String>>(&mut self, id: S) -> &mut Self {
self.headers.insert("id".into(), Value::String(id.into()));
self
}
pub fn build(&self) -> Request {
Request {
url: self.url.clone(),
method: Option::from(self.method.clone()),
headers: self.headers.clone(),
body: self.body.clone(),
}
}
}
#[test]
fn test() {
let mut cookies = HashMap::new();
let mut cookieList = Vec::new();
cookies.insert("id", "asdfsa");
cookies.insert("name", "zxj");
for (key, value) in cookies {
cookieList.push(format!("{}={}", key, value));
}
let cookieString: String = cookieList.iter().map(|cookie| String::from(cookie) + "; ").collect();
println!("{}", cookieString)
}