1use crate::{WebError, WebErrorKind, WebRequest};
2use anyhow::{Error, Result};
3use bytes::Bytes;
4use framework_core::MultiStringValue;
5use framework_core::types::R;
6use futures_util::stream::BoxStream;
7use serde::Serialize;
8use serde_json::json;
9use std::marker::PhantomData;
10use std::ops::{Deref, DerefMut};
11
12const INTERNAL_ERROR_BODY: &[u8] = br#"{"code":500,"message":"Server Error"}"#;
13
14pub enum WebBody {
16 Bytes(Bytes),
18 Stream(BoxStream<'static, Result<Bytes, std::io::Error>>),
20}
21
22impl WebBody {
23 pub fn is_stream(&self) -> bool {
25 matches!(self, Self::Stream(_))
26 }
27}
28
29impl Default for WebBody {
30 fn default() -> Self {
31 Self::Bytes(Bytes::new())
32 }
33}
34
35impl From<Bytes> for WebBody {
36 fn from(value: Bytes) -> Self {
37 Self::Bytes(value)
38 }
39}
40
41impl From<Vec<u8>> for WebBody {
42 fn from(value: Vec<u8>) -> Self {
43 Self::Bytes(Bytes::from(value))
44 }
45}
46
47impl From<String> for WebBody {
48 fn from(value: String) -> Self {
49 Self::Bytes(Bytes::from(value))
50 }
51}
52
53impl From<BoxStream<'static, Result<Bytes, std::io::Error>>> for WebBody {
54 fn from(value: BoxStream<'static, Result<Bytes, std::io::Error>>) -> Self {
55 Self::Stream(value)
56 }
57}
58
59pub struct WebResponse {
60 pub status: u16,
61 pub headers: MultiStringValue,
62 pub body: WebBody,
63}
64
65pub struct WebResponseOf<T> {
72 response: WebResponse,
73 payload: PhantomData<fn() -> T>,
74}
75
76impl<T> WebResponseOf<T> {
77 pub fn from_t(value: T, request: Option<&WebRequest>) -> Self
79 where
80 T: Serialize,
81 {
82 Self::from_response(WebResponse::from_t(value, request))
83 }
84
85 pub fn from_result_t(result: Result<T>, request: Option<&WebRequest>) -> Self
87 where
88 T: Serialize,
89 {
90 Self::from_response(WebResponse::from_result_t(result, request))
91 }
92
93 pub fn from_response(response: WebResponse) -> Self {
95 Self {
96 response,
97 payload: PhantomData,
98 }
99 }
100
101 pub fn into_response(self) -> WebResponse {
103 self.response
104 }
105}
106
107impl<T> Deref for WebResponseOf<T> {
108 type Target = WebResponse;
109
110 fn deref(&self) -> &Self::Target {
111 &self.response
112 }
113}
114
115impl<T> DerefMut for WebResponseOf<T> {
116 fn deref_mut(&mut self) -> &mut Self::Target {
117 &mut self.response
118 }
119}
120
121impl WebResponse {
122 pub fn empty() -> Self {
123 Self {
124 status: 204,
125 headers: MultiStringValue::default(),
126 body: WebBody::Bytes(Bytes::new()),
127 }
128 }
129
130 pub fn from_error(error: Error, request: Option<&WebRequest>) -> Self {
131 let error = normalize_error(error);
132 WebError::log(&error, request);
133 Self::error_body(&error)
134 }
135
136 pub fn from_error_request(error: Error, trace_id: &str, method: &str, path: &str) -> Self {
137 let error = normalize_error(error);
138 WebError::log_request(&error, trace_id, method, path);
139 Self::error_body(&error)
140 }
141
142 fn error_body(error: &WebError) -> Self {
143 let status = error.status();
144 let message = error.public_message();
145 Self::json(status, &json!({ "code": status, "message": message }))
146 }
147
148 pub fn from_result(result: Result<Self>, request: Option<&WebRequest>) -> Self {
149 match result {
150 Ok(response) => response,
151 Err(error) => Self::from_error(error, request),
152 }
153 }
154
155 pub fn from_t<T>(value: T, request: Option<&WebRequest>) -> Self
156 where
157 T: Serialize,
158 {
159 let r = R::ok(value);
160 Self::serialize(&r, request)
161 }
162
163 pub fn from_r<T>(value: R<T>, request: Option<&WebRequest>) -> Self
164 where
165 T: Serialize,
166 {
167 Self::serialize(&value, request)
168 }
169
170 pub fn from_result_t<T>(result: Result<T>, request: Option<&WebRequest>) -> Self
171 where
172 T: Serialize,
173 {
174 match result {
175 Ok(value) => Self::from_t(value, request),
176 Err(error) => Self::from_error(error, request),
177 }
178 }
179
180 pub fn from_result_r<T>(result: Result<R<T>>, request: Option<&WebRequest>) -> Self
181 where
182 T: Serialize,
183 {
184 match result {
185 Ok(value) => Self::from_r(value, request),
186 Err(error) => Self::from_error(error, request),
187 }
188 }
189
190 fn serialize<T>(value: &T, request: Option<&WebRequest>) -> Self
191 where
192 T: Serialize,
193 {
194 match serde_json::to_vec(value) {
195 Ok(body) => Self::json_bytes(200, body),
196 Err(error) => Self::from_error(
197 Error::from(WebError::return_conversion("返回值 JSON 序列化失败", error)),
198 request,
199 ),
200 }
201 }
202
203 fn json<T>(status: u16, value: &T) -> Self
204 where
205 T: Serialize,
206 {
207 match serde_json::to_vec(value) {
208 Ok(body) => Self::json_bytes(status, body),
209 Err(_) => Self::json_bytes(500, INTERNAL_ERROR_BODY.to_vec()),
210 }
211 }
212
213 fn json_bytes(status: u16, body: Vec<u8>) -> Self {
214 let mut headers = MultiStringValue::default();
215 headers.set_content_type("application/json; charset=utf-8");
216 headers.set_content_length(body.len());
217 Self {
218 status,
219 headers,
220 body: WebBody::Bytes(Bytes::from(body)),
221 }
222 }
223
224 pub fn stream(
226 status: u16,
227 content_type: &str,
228 stream: BoxStream<'static, Result<Bytes, std::io::Error>>,
229 ) -> Self {
230 let mut headers = MultiStringValue::default();
231 headers.set_content_type(content_type);
232 Self {
233 status,
234 headers,
235 body: WebBody::Stream(stream),
236 }
237 }
238}
239
240fn normalize_error(error: Error) -> WebError {
241 error.downcast::<WebError>().unwrap_or_else(|error| {
242 if let Some(message) = error.downcast_ref::<&'static str>() {
243 WebError::with_source(WebErrorKind::Message, *message, error)
244 } else if let Some(message) = error.downcast_ref::<String>() {
245 WebError::with_source(WebErrorKind::Message, message.clone(), error)
246 } else {
247 WebError::internal("请求处理发生内部错误", error)
248 }
249 })
250}