-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
179 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
148 changes: 148 additions & 0 deletions
148
golem-worker-service-base/src/api_definition/http/http_response_mapping.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
use std::collections::HashMap; | ||
use std::ops::Deref; | ||
use crate::expression::Expr; | ||
use crate::worker_binding::ResponseMapping; | ||
|
||
pub struct HttpResponseMapping { | ||
pub body: Expr, // ${function.return} | ||
pub status: Expr, // "200" or if ${response.body.id == 1} "200" else "400" | ||
pub headers: HashMap<String, Expr>, | ||
} | ||
|
||
impl TryFrom<&ResponseMapping> for HttpResponseMapping { | ||
type Error = String; | ||
|
||
fn try_from(response_mapping: &ResponseMapping) -> Result<Self, Self::Error> { | ||
let mut headers = HashMap::new(); | ||
let generic_expr = &response_mapping.0; | ||
|
||
match generic_expr { | ||
Expr::Record(obj) => { | ||
let mut body = None; | ||
let mut status = None; | ||
|
||
for (key, value) in obj { | ||
match key.as_str() { | ||
"body" => body = Some(value), | ||
"status" => status = Some(value), | ||
"headers" => { | ||
if let Expr::Record(headers_obj) = value.as_ref().clone() { | ||
for (header_key, header_value) in headers_obj { | ||
headers.insert(header_key.clone(), header_value.as_ref().clone()); | ||
} | ||
} else { | ||
return Err("headers must be an object".to_string()); | ||
} | ||
} | ||
_ => return Err(format!("Unknown key: {}", key)), | ||
} | ||
} | ||
|
||
match (body, status) { | ||
(Some(body), Some(status)) => Ok(HttpResponseMapping { | ||
body: body.as_ref().clone(), | ||
status: status.as_ref().clone(), | ||
headers, | ||
}), | ||
(None, _) => Err("body is required in http response mapping".to_string()), | ||
(_, None) => Err("status is required in http response mapping".to_string()), | ||
} | ||
} | ||
_ => Err("response mapping must be a record".to_string()), | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use crate::expression::Expr; | ||
use crate::worker_binding::ResponseMapping; | ||
|
||
#[test] | ||
fn test_try_from_response_mapping() { | ||
let response_mapping = ResponseMapping(Expr::Record( | ||
vec![ | ||
("body".to_string(), Box::new(Expr::Variable("function.return".to_string()))), | ||
("status".to_string(), Box::new(Expr::Literal("200".to_string()))), | ||
( | ||
"headers".to_string(), | ||
Box::new(Expr::Record(vec![("Content-Type".to_string(), Box::new(Expr::Literal("application/json".to_string())))])), | ||
), | ||
] | ||
.into_iter() | ||
.collect(), | ||
)); | ||
|
||
let http_response_mapping = HttpResponseMapping::try_from(&response_mapping).unwrap(); | ||
|
||
assert_eq!(http_response_mapping.body, Expr::Variable("function.return".to_string())); | ||
assert_eq!(http_response_mapping.status, Expr::Literal("200".to_string())); | ||
assert_eq!(http_response_mapping.headers.len(), 1); | ||
assert_eq!(http_response_mapping.headers.get("Content-Type").unwrap(), &Expr::Literal("application/json".to_string())); | ||
} | ||
|
||
#[test] | ||
fn test_try_from_response_mapping_missing_body() { | ||
let response_mapping = ResponseMapping(Expr::Record( | ||
vec![ | ||
("status".to_string(), Box::new(Expr::Literal("200".to_string()))), | ||
( | ||
"headers".to_string(), | ||
Box::new(Expr::Record(vec![("Content-Type".to_string(), Box::new(Expr::Literal("application/json".to_string())))])), | ||
), | ||
] | ||
.into_iter() | ||
.collect(), | ||
)); | ||
|
||
let result = HttpResponseMapping::try_from(&response_mapping); | ||
|
||
assert_eq!(result, Err("body is required in http response mapping".to_string())); | ||
} | ||
|
||
#[test] | ||
fn test_try_from_response_mapping_missing_status() { | ||
let response_mapping = ResponseMapping(Expr::Record( | ||
vec![ | ||
("body".to_string(), Expr::Variable("function.return".to_string())), | ||
( | ||
"headers".to_string(), | ||
Expr::Record(vec![("Content-Type".to_string(), Box:new(Expr::Literal("application/json".to_string())))]), | ||
), | ||
] | ||
.into_iter() | ||
.collect(), | ||
)); | ||
|
||
let result = HttpResponseMapping::try_from(&response_mapping); | ||
|
||
assert_eq!(result, Err("status is required in http response mapping".to_string())); | ||
} | ||
|
||
#[test] | ||
fn test_try_from_response_mapping_headers_not_object() { | ||
let response_mapping = ResponseMapping(Expr::Record( | ||
vec![ | ||
("body".to_string(), Expr::Variable("function.return".to_string())), | ||
("status".to_string(), Expr::Literal("200".to_string())), | ||
("headers".to_string(), Expr::Literal("application/json".to_string())), | ||
] | ||
.into_iter() | ||
.collect(), | ||
)); | ||
|
||
let result = HttpResponseMapping::try_from(&response_mapping); | ||
|
||
assert_eq!(result, Err("headers must be an object".to_string())); | ||
} | ||
|
||
#[test] | ||
fn test_try_from_response_mapping_not_record() { | ||
let response_mapping = ResponseMapping(Expr::Literal("200".to_string())); | ||
|
||
let result = HttpResponseMapping::try_from(&response_mapping); | ||
|
||
assert_eq!(result, Err("response mapping must be a record".to_string())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
pub use http_api_definition::*; | ||
pub use http_oas_api_definition::get_api_definition_from_oas; | ||
pub(crate) use http_response_mapping::HttpResponseMapping; | ||
|
||
mod http_api_definition; | ||
mod http_oas_api_definition; | ||
|
||
mod http_response_mapping; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters