use crate::{
http::Body,
rpc::{typed_data::Data, RpcHttp, TypedData},
};
use std::collections::HashMap;
#[derive(Debug)]
pub struct HttpRequest(RpcHttp);
impl HttpRequest {
#[doc(hidden)]
pub fn new(data: TypedData, _: HashMap<String, TypedData>) -> Self {
match data.data {
Some(Data::Http(http)) => HttpRequest(*http),
_ => panic!("unexpected type data for HTTP request."),
}
}
pub fn method(&self) -> &str {
&self.0.method
}
pub fn url(&self) -> &str {
&self.0.url
}
pub fn headers(&self) -> &HashMap<String, String> {
&self.0.headers
}
pub fn route_params(&self) -> &HashMap<String, String> {
&self.0.params
}
pub fn query_params(&self) -> &HashMap<String, String> {
&self.0.query
}
pub fn body(&self) -> Body {
self.0
.body
.as_ref()
.map(|b| Body::from(&**b))
.unwrap_or(Body::Empty)
}
}
#[cfg(test)]
mod tests {
use super::*;
use matches::matches;
use std::borrow::Cow;
#[test]
fn it_has_the_method() {
const METHOD: &'static str = "GET";
let mut http = RpcHttp::default();
http.method = METHOD.to_string();
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert_eq!(request.method(), METHOD);
}
#[test]
fn it_has_the_url() {
const URL: &'static str = "http://example.com";
let mut http = RpcHttp::default();
http.url = URL.to_string();
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert_eq!(request.url(), URL);
}
#[test]
fn it_has_a_header() {
const KEY: &'static str = "Accept";
const VALUE: &'static str = "application/json";
let mut http = RpcHttp::default();
http.headers.insert(KEY.to_string(), VALUE.to_string());
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert_eq!(request.headers().get(KEY).unwrap(), VALUE);
}
#[test]
fn it_has_a_route_parameter() {
const KEY: &'static str = "id";
const VALUE: &'static str = "12345";
let mut http = RpcHttp::default();
http.params.insert(KEY.to_string(), VALUE.to_string());
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert_eq!(request.route_params().get(KEY).unwrap(), VALUE);
}
#[test]
fn it_has_a_query_parameter() {
const KEY: &'static str = "name";
const VALUE: &'static str = "Peter";
let mut http = RpcHttp::default();
http.query.insert(KEY.to_string(), VALUE.to_string());
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert_eq!(request.query_params().get(KEY).unwrap(), VALUE);
}
#[test]
fn it_has_an_empty_body() {
let data = TypedData {
data: Some(Data::Http(Box::new(RpcHttp::default()))),
};
let request = HttpRequest::new(data, HashMap::new());
assert!(matches!(request.body(), Body::Empty));
}
#[test]
fn it_has_a_string_body() {
const BODY: &'static str = "TEXT BODY";
let mut http = RpcHttp::default();
http.body = Some(Box::new(TypedData {
data: Some(Data::String(BODY.to_string())),
}));
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert!(matches!(request.body(), Body::String(Cow::Borrowed(BODY))));
}
#[test]
fn it_has_a_json_body() {
const BODY: &'static str = r#"{ "json": "body" }"#;
let mut http = RpcHttp::default();
http.body = Some(Box::new(TypedData {
data: Some(Data::Json(BODY.to_string())),
}));
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert!(matches!(request.body(), Body::Json(Cow::Borrowed(BODY))));
}
#[test]
fn it_has_a_bytes_body() {
const BODY: &'static [u8] = &[0, 1, 2];
let mut http = RpcHttp::default();
http.body = Some(Box::new(TypedData {
data: Some(Data::Bytes(BODY.to_vec())),
}));
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert!(matches!(request.body(), Body::Bytes(Cow::Borrowed(BODY))));
}
#[test]
fn it_has_a_stream_body() {
const BODY: &'static [u8] = &[0, 1, 2];
let mut http = RpcHttp::default();
http.body = Some(Box::new(TypedData {
data: Some(Data::Stream(BODY.to_vec())),
}));
let data = TypedData {
data: Some(Data::Http(Box::new(http))),
};
let request = HttpRequest::new(data, HashMap::new());
assert!(matches!(request.body(), Body::Bytes(Cow::Borrowed(BODY))));
}
}