Start writing more tests

This commit is contained in:
David Pedersen
2021-05-31 12:22:16 +02:00
parent 6822766165
commit 593c901aab
5 changed files with 259 additions and 196 deletions
+56 -11
View File
@@ -1,7 +1,7 @@
use crate::{body::Body, Error};
use bytes::Bytes;
use futures_util::{future, ready};
use http::Request;
use http::{header, Request, StatusCode};
use pin_project::pin_project;
use serde::de::DeserializeOwned;
use std::{
@@ -86,20 +86,39 @@ where
type Future = future::BoxFuture<'static, Result<Self, Error>>;
fn from_request(req: &mut Request<Body>) -> Self::Future {
// TODO(david): require the body to have `content-type: application/json`
if has_content_type(&req, "application/json") {
let body = std::mem::take(req.body_mut());
let body = std::mem::take(req.body_mut());
Box::pin(async move {
let bytes = hyper::body::to_bytes(body)
.await
.map_err(Error::ConsumeRequestBody)?;
let value = serde_json::from_slice(&bytes).map_err(Error::DeserializeRequestBody)?;
Ok(Json(value))
})
Box::pin(async move {
let bytes = hyper::body::to_bytes(body)
.await
.map_err(Error::ConsumeRequestBody)?;
let value =
serde_json::from_slice(&bytes).map_err(Error::DeserializeRequestBody)?;
Ok(Json(value))
})
} else {
Box::pin(async { Err(Error::Status(StatusCode::BAD_REQUEST)) })
}
}
}
fn has_content_type<B>(req: &Request<B>, expected_content_type: &str) -> bool {
let content_type = if let Some(content_type) = req.headers().get(header::CONTENT_TYPE) {
content_type
} else {
return false;
};
let content_type = if let Ok(content_type) = content_type.to_str() {
content_type
} else {
return false;
};
content_type.starts_with(expected_content_type)
}
#[derive(Debug, Clone, Copy)]
pub struct Extension<T>(T);
@@ -146,6 +165,32 @@ impl FromRequest for Bytes {
}
}
impl FromRequest for String {
type Future = future::BoxFuture<'static, Result<Self, Error>>;
fn from_request(req: &mut Request<Body>) -> Self::Future {
let body = std::mem::take(req.body_mut());
Box::pin(async move {
let bytes = hyper::body::to_bytes(body)
.await
.map_err(Error::ConsumeRequestBody)?
.to_vec();
let string = String::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
Ok(string)
})
}
}
impl FromRequest for Body {
type Future = future::Ready<Result<Self, Error>>;
fn from_request(req: &mut Request<Body>) -> Self::Future {
let body = std::mem::take(req.body_mut());
future::ok(body)
}
}
#[derive(Debug, Clone)]
pub struct BytesMaxLength<const N: u64>(Bytes);