use std::collections::HashMap;
use aws_lambda_events::event::apigw::ApiGatewayProxyRequest;
use serde_json::Value;
use crate::components::HttpMethod;
pub struct SrvrlsRequest {
pub query_parameters: HashMap<String, Vec<String>>,
pub path: String,
pub string_claims: HashMap<String, String>,
pub integer_claims: HashMap<String, i64>,
pub method: HttpMethod,
pub body: String,
}
impl Default for SrvrlsRequest {
fn default() -> Self {
SrvrlsRequest {
query_parameters: Default::default(),
path: "".to_string(),
string_claims: Default::default(),
integer_claims: Default::default(),
method: HttpMethod::GET,
body: "".to_string(),
}
}
}
impl SrvrlsRequest {
pub fn path_parameter(&self, position: usize) -> String {
let parameters: Vec<&str> = self.path.split('/').collect();
match parameters.get(position) {
None => "".to_string(),
Some(parameter) => parameter.to_string(),
}
}
pub fn query_parameter(&self, key: &str) -> Vec<String> {
match self.query_parameters.get(key) {
None => Vec::new(),
Some(v) => v.clone(),
}
}
pub fn authentication_claim(&self, claim: &str) -> String {
match self.string_claims.get(claim) {
None => "".to_string(),
Some(value) => value.clone(),
}
}
}
impl From<ApiGatewayProxyRequest> for SrvrlsRequest {
fn from(event: ApiGatewayProxyRequest) -> Self {
let path = event.path_parameters["proxy"].clone();
let mut query_string_parameters = event.multi_value_query_string_parameters;
for (k, v) in event.query_string_parameters {
query_string_parameters.insert(k, vec![v]);
}
let method = match event.http_method {
None => HttpMethod::OTHER,
Some(method) => {
match method.as_str() {
"GET" => HttpMethod::GET,
"POST" => HttpMethod::POST,
"PUT" => HttpMethod::PUT,
"HEAD" => HttpMethod::HEAD,
"DELETE" => HttpMethod::DELETE,
_ => HttpMethod::OTHER,
}
}
};
let body = match event.body {
None => "".to_string(),
Some(body) => body.clone(),
};
let mut string_claims = HashMap::new();
let mut integer_claims = HashMap::new();
match event.request_context.authorizer.get("claims") {
None => {}
Some(claims) => {
match serde_json::to_value(claims).unwrap() {
Value::Null |
Value::Bool(_) |
Value::Number(_) |
Value::String(_) |
Value::Array(_) => { panic!() }
Value::Object(claims) => {
for (k, v) in claims {
match v {
Value::Null => {}
Value::Bool(_) => {}
Value::Number(number_value) => {
if number_value.is_i64() {
integer_claims.insert(k, number_value.as_i64().unwrap());
}
}
Value::String(string_value) => {
string_claims.insert(k, string_value);
}
Value::Array(_) => {}
Value::Object(_) => {}
};
}
}
};
}
};
SrvrlsRequest {
path,
string_claims,
integer_claims,
query_parameters: query_string_parameters,
method,
body,
}
}
}
#[cfg(test)]
mod request_tests {
use crate::components::{HttpMethod, SrvrlsError};
use crate::request::SrvrlsRequest;
use crate::response::SrvrlsResponse;
#[test]
fn test_path() {
let mut request: SrvrlsRequest = Default::default();
request.path = "customer/update/CUST-A23948".to_string();
assert_eq!("customer", request.path_parameter(0));
assert_eq!("update", request.path_parameter(1));
assert_eq!("CUST-A23948", request.path_parameter(2));
}
#[test]
fn test_complex_switch() {
let mut request: SrvrlsRequest = Default::default();
request.path = "customer/update/CUST-A23948".to_string();
assert_eq!("customer", request.path_parameter(0));
assert_eq!("update", request.path_parameter(1));
assert_eq!("CUST-A23948", request.path_parameter(2));
let mut request: SrvrlsRequest = Default::default();
request.method = HttpMethod::POST;
request.path = "customer/CUST-A23948".to_string();
assert_eq!(SrvrlsResponse::no_content(), test_handler(request).unwrap());
let mut request: SrvrlsRequest = Default::default();
request.method = HttpMethod::POST;
request.path = "account/ACCT-G10291".to_string();
assert_eq!(SrvrlsResponse::created(), test_handler(request).unwrap());
let mut request: SrvrlsRequest = Default::default();
request.method = HttpMethod::GET;
request.path = "customer/CUST-A23948".to_string();
assert_eq!(SrvrlsResponse::ok_empty(), test_handler(request).unwrap());
let mut request: SrvrlsRequest = Default::default();
request.method = HttpMethod::GET;
request.path = "account/ACCT-G10291".to_string();
assert_eq!(SrvrlsError::NotFound, test_handler(request).unwrap_err());
}
fn test_handler(request: SrvrlsRequest) -> Result<SrvrlsResponse, SrvrlsError> {
match (&request.method, request.path_parameter(0).as_str()) {
(HttpMethod::POST, "customer") => Ok(SrvrlsResponse::no_content()),
(HttpMethod::POST, "account") => Ok(SrvrlsResponse::created()),
(HttpMethod::GET, "customer") => Ok(SrvrlsResponse::ok_empty()),
_ => return Err(SrvrlsError::NotFound)
}
}
}