Skip to content

Commit 2995b44

Browse files
authored
Merge pull request #33 from tzilist/master
Adding String and Vec Body Types
2 parents 04321df + 4925028 commit 2995b44

File tree

3 files changed

+101
-3
lines changed

3 files changed

+101
-3
lines changed

examples/body_types.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![feature(async_await, futures_api)]
2+
3+
#[macro_use]
4+
extern crate serde_derive;
5+
use tide::body;
6+
7+
#[derive(Serialize, Deserialize, Clone, Debug)]
8+
struct Message {
9+
author: Option<String>,
10+
contents: String,
11+
}
12+
13+
async fn echo_string(msg: body::Str) -> String {
14+
println!("String: {}", msg.0);
15+
format!("{}", msg.0)
16+
}
17+
18+
async fn echo_string_lossy(msg: body::StrLossy) -> String {
19+
println!("String: {}", msg.0);
20+
format!("{}", msg.0)
21+
}
22+
23+
async fn echo_vec(msg: body::Bytes) -> String {
24+
println!("Vec<u8>: {:?}", msg.0);
25+
26+
String::from_utf8(msg.0).unwrap()
27+
}
28+
29+
async fn echo_json(msg: body::Json<Message>) -> body::Json<Message> {
30+
println!("JSON: {:?}", msg.0);
31+
32+
msg
33+
}
34+
35+
fn main() {
36+
let mut app = tide::App::new(());
37+
app.at("/echo/string").post(echo_string);
38+
app.at("/echo/string_lossy").post(echo_string_lossy);
39+
app.at("/echo/vec").post(echo_vec);
40+
app.at("/echo/json").post(echo_json);
41+
app.serve("127.0.0.1:8000");
42+
}

rustfmt.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
edition = "2018"
2+
tab_spaces = 4

src/body.rs

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ impl Into<hyper::Body> for Body {
112112
}
113113
}
114114

115+
// Small utility function to return a stamped error when we cannot parse a request body
116+
fn mk_err<T>(_: T) -> Response {
117+
StatusCode::BAD_REQUEST.into_response()
118+
}
119+
115120
/// A wrapper for json (de)serialization of bodies.
116121
///
117122
/// This type is usable both as an extractor (argument to an endpoint) and as a response
@@ -126,9 +131,6 @@ impl<T: Send + serde::de::DeserializeOwned + 'static, S: 'static> Extract<S> for
126131
let mut body = std::mem::replace(req.body_mut(), Body::empty());
127132
FutureObj::new(Box::new(
128133
async move {
129-
fn mk_err<T>(_: T) -> Response {
130-
StatusCode::BAD_REQUEST.into_response()
131-
}
132134
let body = await!(body.read_to_vec()).map_err(mk_err)?;
133135
let json: T = serde_json::from_slice(&body).map_err(mk_err)?;
134136
Ok(Json(json))
@@ -147,3 +149,56 @@ impl<T: 'static + Send + serde::Serialize> IntoResponse for Json<T> {
147149
.unwrap()
148150
}
149151
}
152+
153+
pub struct Str(pub String);
154+
155+
impl<S: 'static> Extract<S> for Str {
156+
type Fut = FutureObj<'static, Result<Self, Response>>;
157+
158+
fn extract(data: &mut S, req: &mut Request, params: &RouteMatch<'_>) -> Self::Fut {
159+
let mut body = std::mem::replace(req.body_mut(), Body::empty());
160+
161+
FutureObj::new(Box::new(
162+
async move {
163+
let body = await!(body.read_to_vec().map_err(mk_err))?;
164+
let string = String::from_utf8(body).map_err(mk_err)?;
165+
Ok(Str(string))
166+
},
167+
))
168+
}
169+
}
170+
171+
pub struct StrLossy(pub String);
172+
173+
impl<S: 'static> Extract<S> for StrLossy {
174+
type Fut = FutureObj<'static, Result<Self, Response>>;
175+
176+
fn extract(data: &mut S, req: &mut Request, params: &RouteMatch<'_>) -> Self::Fut {
177+
let mut body = std::mem::replace(req.body_mut(), Body::empty());
178+
179+
FutureObj::new(Box::new(
180+
async move {
181+
let body = await!(body.read_to_vec().map_err(mk_err))?;
182+
let string = String::from_utf8_lossy(&body).to_string();
183+
Ok(StrLossy(string))
184+
},
185+
))
186+
}
187+
}
188+
189+
pub struct Bytes(pub Vec<u8>);
190+
191+
impl<S: 'static> Extract<S> for Bytes {
192+
type Fut = FutureObj<'static, Result<Self, Response>>;
193+
194+
fn extract(data: &mut S, req: &mut Request, params: &RouteMatch<'_>) -> Self::Fut {
195+
let mut body = std::mem::replace(req.body_mut(), Body::empty());
196+
197+
FutureObj::new(Box::new(
198+
async move {
199+
let body = await!(body.read_to_vec().map_err(mk_err))?;
200+
Ok(Bytes(body))
201+
},
202+
))
203+
}
204+
}

0 commit comments

Comments
 (0)