1use http::StatusCode;
4
5use crate::service::{AwsRequest, AwsServiceError};
6
7pub fn query_response_xml(action: &str, namespace: &str, inner: &str, request_id: &str) -> String {
18 format!(
19 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
20 <{action}Response xmlns=\"{namespace}\">\
21 <{action}Result>{inner}</{action}Result>\
22 <ResponseMetadata><RequestId>{request_id}</RequestId></ResponseMetadata>\
23 </{action}Response>"
24 )
25}
26
27pub fn query_metadata_only_xml(action: &str, namespace: &str, request_id: &str) -> String {
29 format!(
30 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
31 <{action}Response xmlns=\"{namespace}\">\
32 <ResponseMetadata><RequestId>{request_id}</RequestId></ResponseMetadata>\
33 </{action}Response>"
34 )
35}
36
37pub fn optional_query_param(req: &AwsRequest, name: &str) -> Option<String> {
41 req.query_params
42 .get(name)
43 .cloned()
44 .filter(|value| !value.is_empty())
45}
46
47pub fn required_query_param(req: &AwsRequest, name: &str) -> Result<String, AwsServiceError> {
51 optional_query_param(req, name).ok_or_else(|| {
52 AwsServiceError::aws_error(
53 StatusCode::BAD_REQUEST,
54 "MissingParameter",
55 format!("The request must contain the parameter {name}."),
56 )
57 })
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63 use bytes::Bytes;
64 use http::HeaderMap;
65 use std::collections::HashMap;
66
67 fn make_req(params: &[(&str, &str)]) -> AwsRequest {
68 let mut query_params = HashMap::new();
69 for (k, v) in params {
70 query_params.insert((*k).to_string(), (*v).to_string());
71 }
72 AwsRequest {
73 service: "x".to_string(),
74 action: "A".to_string(),
75 region: "us-east-1".to_string(),
76 account_id: "123".to_string(),
77 request_id: "r".to_string(),
78 headers: HeaderMap::new(),
79 query_params,
80 body: Bytes::new(),
81 path_segments: vec![],
82 raw_path: "/".to_string(),
83 raw_query: String::new(),
84 method: http::Method::POST,
85 is_query_protocol: true,
86 access_key_id: None,
87 principal: None,
88 }
89 }
90
91 #[test]
92 fn query_response_xml_format() {
93 let xml = query_response_xml("Foo", "http://example.com/", "<Bar/>", "req-1");
94 assert!(xml.contains("<FooResponse"));
95 assert!(xml.contains("<FooResult><Bar/></FooResult>"));
96 assert!(xml.contains("<RequestId>req-1</RequestId>"));
97 }
98
99 #[test]
100 fn query_metadata_only_xml_omits_result() {
101 let xml = query_metadata_only_xml("Foo", "http://example.com/", "req-1");
102 assert!(xml.contains("<FooResponse"));
103 assert!(!xml.contains("<FooResult"));
104 assert!(xml.contains("<RequestId>req-1</RequestId>"));
105 }
106
107 #[test]
108 fn optional_query_param_returns_value() {
109 let req = make_req(&[("key", "value")]);
110 assert_eq!(optional_query_param(&req, "key").as_deref(), Some("value"));
111 }
112
113 #[test]
114 fn optional_query_param_missing_returns_none() {
115 let req = make_req(&[]);
116 assert!(optional_query_param(&req, "key").is_none());
117 }
118
119 #[test]
120 fn optional_query_param_empty_returns_none() {
121 let req = make_req(&[("key", "")]);
122 assert!(optional_query_param(&req, "key").is_none());
123 }
124
125 #[test]
126 fn required_query_param_returns_value() {
127 let req = make_req(&[("k", "v")]);
128 assert_eq!(required_query_param(&req, "k").unwrap(), "v");
129 }
130
131 #[test]
132 fn required_query_param_missing_errors() {
133 let req = make_req(&[]);
134 assert!(required_query_param(&req, "k").is_err());
135 }
136}