aws_lambda_router/
response.rs1use serde::{Deserialize, Serialize};
2use serde_json::{json, Value};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Response {
8 #[serde(rename = "statusCode")]
9 pub status_code: u16,
10 pub headers: HashMap<String, String>,
11 pub body: String,
12 #[serde(rename = "isBase64Encoded")]
13 pub is_base64_encoded: bool,
14}
15
16impl Response {
17 pub fn new(status_code: u16) -> Self {
19 let mut headers = HashMap::new();
20 headers.insert("Content-Type".to_string(), "application/json".to_string());
21
22 Self {
23 status_code,
24 headers,
25 body: String::new(),
26 is_base64_encoded: false,
27 }
28 }
29
30 pub fn json(mut self, body: Value) -> Self {
32 self.body = body.to_string();
33 self.headers
34 .insert("Content-Type".to_string(), "application/json".to_string());
35 self
36 }
37
38 pub fn json_body<T: Serialize>(mut self, body: &T) -> Self {
40 self.body = serde_json::to_string(body).unwrap_or_else(|_| "{}".to_string());
41 self.headers
42 .insert("Content-Type".to_string(), "application/json".to_string());
43 self
44 }
45
46 pub fn text(mut self, body: impl Into<String>) -> Self {
48 self.body = body.into();
49 self.headers
50 .insert("Content-Type".to_string(), "text/plain".to_string());
51 self
52 }
53
54 pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
56 self.headers.insert(key.into(), value.into());
57 self
58 }
59
60 pub fn headers(mut self, headers: HashMap<String, String>) -> Self {
62 self.headers.extend(headers);
63 self
64 }
65
66 pub fn with_cors(mut self) -> Self {
68 self.headers
69 .insert("Access-Control-Allow-Origin".to_string(), "*".to_string());
70 self.headers.insert(
71 "Access-Control-Allow-Methods".to_string(),
72 "GET, POST, PUT, DELETE, OPTIONS".to_string(),
73 );
74 self.headers.insert(
75 "Access-Control-Allow-Headers".to_string(),
76 "Content-Type, Authorization".to_string(),
77 );
78 self.headers
79 .insert("Access-Control-Max-Age".to_string(), "3600".to_string());
80 self
81 }
82
83 pub fn to_json(&self) -> Value {
85 json!({
86 "statusCode": self.status_code,
87 "headers": self.headers,
88 "body": self.body,
89 "isBase64Encoded": self.is_base64_encoded
90 })
91 }
92
93 pub fn from_json_value(value: Value) -> Self {
96 let status_code = value["statusCode"].as_u64().unwrap_or(200) as u16;
97
98 let mut headers = HashMap::new();
99 if let Some(headers_obj) = value["headers"].as_object() {
100 for (key, val) in headers_obj {
101 if let Some(s) = val.as_str() {
102 headers.insert(key.clone(), s.to_string());
103 }
104 }
105 }
106
107 let body = if let Some(body_str) = value["body"].as_str() {
109 body_str.to_string()
110 } else {
111 serde_json::to_string(&value["body"]).unwrap_or_else(|_| value["body"].to_string())
113 };
114
115 Self {
116 status_code,
117 headers,
118 body,
119 is_base64_encoded: value["isBase64Encoded"].as_bool().unwrap_or(false),
120 }
121 }
122
123 pub fn ok(body: Value) -> Self {
127 Self::new(200).json(body).with_cors()
128 }
129
130 pub fn created(body: Value) -> Self {
132 Self::new(201).json(body).with_cors()
133 }
134
135 pub fn no_content() -> Self {
137 Self::new(204).with_cors()
138 }
139
140 pub fn bad_request(message: &str) -> Self {
142 Self::new(400)
143 .json(json!({
144 "error": "Bad Request",
145 "message": message
146 }))
147 .with_cors()
148 }
149
150 pub fn unauthorized(message: &str) -> Self {
152 Self::new(401)
153 .json(json!({
154 "error": "Unauthorized",
155 "message": message
156 }))
157 .with_cors()
158 }
159
160 pub fn forbidden(message: &str) -> Self {
162 Self::new(403)
163 .json(json!({
164 "error": "Forbidden",
165 "message": message
166 }))
167 .with_cors()
168 }
169
170 pub fn not_found(message: &str) -> Self {
172 Self::new(404)
173 .json(json!({
174 "error": "Not Found",
175 "message": message
176 }))
177 .with_cors()
178 }
179
180 pub fn method_not_allowed(message: &str) -> Self {
182 Self::new(405)
183 .json(json!({
184 "error": "Method Not Allowed",
185 "message": message
186 }))
187 .with_cors()
188 }
189
190 pub fn internal_error(message: &str) -> Self {
192 Self::new(500)
193 .json(json!({
194 "error": "Internal Server Error",
195 "message": message
196 }))
197 .with_cors()
198 }
199
200 pub fn cors_preflight() -> Self {
202 Self::new(200).text("").with_cors()
203 }
204}