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 body_stream: parking_lot::Mutex::new(None),
82 path_segments: vec![],
83 raw_path: "/".to_string(),
84 raw_query: String::new(),
85 method: http::Method::POST,
86 is_query_protocol: true,
87 access_key_id: None,
88 principal: None,
89 }
90 }
91
92 #[test]
93 fn query_response_xml_format() {
94 let xml = query_response_xml("Foo", "http://example.com/", "<Bar/>", "req-1");
95 assert!(xml.contains("<FooResponse"));
96 assert!(xml.contains("<FooResult><Bar/></FooResult>"));
97 assert!(xml.contains("<RequestId>req-1</RequestId>"));
98 }
99
100 #[test]
101 fn query_metadata_only_xml_omits_result() {
102 let xml = query_metadata_only_xml("Foo", "http://example.com/", "req-1");
103 assert!(xml.contains("<FooResponse"));
104 assert!(!xml.contains("<FooResult"));
105 assert!(xml.contains("<RequestId>req-1</RequestId>"));
106 }
107
108 #[test]
109 fn optional_query_param_returns_value() {
110 let req = make_req(&[("key", "value")]);
111 assert_eq!(optional_query_param(&req, "key").as_deref(), Some("value"));
112 }
113
114 #[test]
115 fn optional_query_param_missing_returns_none() {
116 let req = make_req(&[]);
117 assert!(optional_query_param(&req, "key").is_none());
118 }
119
120 #[test]
121 fn optional_query_param_empty_returns_none() {
122 let req = make_req(&[("key", "")]);
123 assert!(optional_query_param(&req, "key").is_none());
124 }
125
126 #[test]
127 fn required_query_param_returns_value() {
128 let req = make_req(&[("k", "v")]);
129 assert_eq!(required_query_param(&req, "k").unwrap(), "v");
130 }
131
132 #[test]
133 fn required_query_param_missing_errors() {
134 let req = make_req(&[]);
135 assert!(required_query_param(&req, "k").is_err());
136 }
137}