micro_web/extract/
extract_body.rs1use crate::RequestContext;
30use crate::body::OptionReqBody;
31use crate::extract::from_request::FromRequest;
32use crate::extract::{Form, Json};
33use bytes::Bytes;
34use http_body_util::BodyExt;
35use micro_http::protocol::ParseError;
36use serde::Deserialize;
37
38impl FromRequest for Bytes {
40 type Output<'any> = Bytes;
41 type Error = ParseError;
42
43 async fn from_request(_req: &RequestContext<'_, '_>, body: OptionReqBody) -> Result<Self::Output<'static>, Self::Error> {
44 body.apply(|b| async { b.collect().await.map(|c| c.to_bytes()) }).await
45 }
46}
47
48impl FromRequest for String {
50 type Output<'any> = String;
51 type Error = ParseError;
52
53 async fn from_request(req: &RequestContext<'_, '_>, body: OptionReqBody) -> Result<Self::Output<'static>, Self::Error> {
54 let bytes = <Bytes as FromRequest>::from_request(req, body).await?;
55 match String::from_utf8(bytes.into()) {
57 Ok(s) => Ok(s),
58 Err(_) => Err(ParseError::invalid_body("request body is not utf8")),
59 }
60 }
61}
62
63impl<T> FromRequest for Form<T>
68where
69 T: for<'de> Deserialize<'de> + Send,
70{
71 type Output<'r> = Form<T>;
72 type Error = ParseError;
73
74 async fn from_request<'r>(req: &'r RequestContext<'_, '_>, body: OptionReqBody) -> Result<Self::Output<'r>, Self::Error> {
75 let bytes = <Bytes as FromRequest>::from_request(req, body).await?;
76 serde_urlencoded::from_bytes::<'_, T>(&bytes).map(|t| Form(t)).map_err(|e| ParseError::invalid_body(e.to_string()))
77 }
78}
79
80impl<T> FromRequest for Json<T>
85where
86 T: for<'de> Deserialize<'de> + Send,
87{
88 type Output<'r> = Json<T>;
89 type Error = ParseError;
90
91 async fn from_request<'r>(req: &'r RequestContext<'_, '_>, body: OptionReqBody) -> Result<Self::Output<'r>, Self::Error> {
92 let bytes = <Bytes as FromRequest>::from_request(req, body).await?;
93 serde_json::from_slice::<'_, T>(&bytes).map(|t| Json(t)).map_err(|e| ParseError::invalid_body(e.to_string()))
94 }
95}