use futures::future::ok;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use warp::{
filters::{multipart, ws::Ws, BoxedFilter},
reply::{json, Response},
Filter, Rejection, Reply,
};
pub trait FromRequest: Sized {
type Filter: Filter<Error = Rejection>;
fn is_body() -> bool {
false
}
fn is_optional() -> bool {
false
}
fn is_query() -> bool {
false
}
fn content_type() -> &'static str {
"*/*"
}
fn new() -> Self::Filter;
}
impl<T> FromRequest for Option<T>
where
T: 'static + FromRequest + Send + Send,
T::Filter: Send + Sync + Filter<Extract = (T,), Error = Rejection>,
{
type Filter = BoxedFilter<(Option<T>,)>;
fn is_body() -> bool {
T::is_body()
}
fn is_optional() -> bool {
true
}
fn is_query() -> bool {
T::is_query()
}
fn new() -> Self::Filter {
T::new()
.map(Some)
.or_else(|_| ok::<_, Rejection>((None,)))
.boxed()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Json<T>(T);
impl<T> Json<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> From<T> for Json<T> {
#[inline]
fn from(v: T) -> Self {
Json(v)
}
}
impl<T> FromRequest for Json<T>
where
T: 'static + Send + DeserializeOwned,
{
type Filter = BoxedFilter<(Json<T>,)>;
fn is_body() -> bool {
true
}
fn content_type() -> &'static str {
"application/json"
}
fn new() -> Self::Filter {
warp::body::json().boxed()
}
}
impl<T> Reply for Json<T>
where
T: Serialize + Send,
{
fn into_response(self) -> Response {
json(&self.0).into_response()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize)]
#[serde(transparent)]
pub struct Form<T>(T);
impl<T> Form<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> FromRequest for Form<T>
where
T: 'static + Send + DeserializeOwned,
{
type Filter = BoxedFilter<(Form<T>,)>;
fn is_body() -> bool {
true
}
fn content_type() -> &'static str {
"x-www-form-urlencoded"
}
fn new() -> Self::Filter {
warp::body::form().boxed()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize)]
#[serde(transparent)]
pub struct Query<T>(T);
impl<T> Query<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> FromRequest for Query<T>
where
T: 'static + Send + DeserializeOwned,
{
type Filter = BoxedFilter<(Query<T>,)>;
fn is_query() -> bool {
true
}
fn new() -> Self::Filter {
warp::query().boxed()
}
}
impl FromRequest for Ws {
type Filter = BoxedFilter<(Ws,)>;
fn new() -> Self::Filter {
warp::ws().boxed()
}
}
impl FromRequest for multipart::FormData {
type Filter = BoxedFilter<(Self,)>;
fn new() -> Self::Filter {
warp::multipart::form().boxed()
}
}