Skip to content

Commit

Permalink
implemented Deref for body types and some Path types, updated examples
Browse files Browse the repository at this point in the history
  • Loading branch information
ibaryshnikov committed Nov 27, 2018
1 parent 853f620 commit 9ae1f13
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 16 deletions.
16 changes: 8 additions & 8 deletions examples/body_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ struct Message {
}

async fn echo_string(msg: body::Str) -> String {
println!("String: {}", msg.0);
format!("{}", msg.0)
println!("String: {}", *msg);
format!("{}", *msg)
}

async fn echo_string_lossy(msg: body::StrLossy) -> String {
println!("String: {}", msg.0);
format!("{}", msg.0)
println!("String: {}", *msg);
format!("{}", *msg)
}

async fn echo_vec(msg: body::Bytes) -> String {
println!("Vec<u8>: {:?}", msg.0);
println!("Vec<u8>: {:?}", *msg);

String::from_utf8(msg.0).unwrap()
String::from_utf8(msg.to_vec()).unwrap()
}

async fn echo_json(msg: body::Json<Message>) -> body::Json<Message> {
println!("JSON: {:?}", msg.0);
println!("JSON: {:?}", *msg);

msg
}

async fn echo_form(msg: body::Form<Message>) -> body::Form<Message> {
println!("Form: {:?}", msg.0);
println!("Form: {:?}", *msg);

msg
}
Expand Down
3 changes: 1 addition & 2 deletions examples/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ async fn handle_graphql(
ctx: AppData<Context>,
query: body::Json<juniper::http::GraphQLRequest>,
) -> Result<Response, StatusCode> {
let request = query.0;
let response = request.execute(&Schema::new(Query, Mutation), &ctx);
let response = query.execute(&Schema::new(Query, Mutation), &ctx);

// `response` has the lifetime of `request`, so we can't use `IntoResponse` directly.
let body_vec = serde_json::to_vec(&response).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Expand Down
6 changes: 3 additions & 3 deletions examples/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ impl Database {
}

async fn new_message(mut db: AppData<Database>, msg: body::Json<Message>) -> String {
db.insert(msg.0).to_string()
db.insert(msg.clone()).to_string()
}

async fn set_message(
mut db: AppData<Database>,
id: head::Path<usize>,
msg: body::Json<Message>,
) -> Result<(), StatusCode> {
if db.set(id.0, msg.0) {
if db.set(*id, msg.clone()) {
Ok(())
} else {
Err(StatusCode::NOT_FOUND)
Expand All @@ -67,7 +67,7 @@ async fn get_message(
mut db: AppData<Database>,
id: head::Path<usize>,
) -> Result<body::Json<Message>, StatusCode> {
if let Some(msg) = db.get(id.0) {
if let Some(msg) = db.get(*id) {
Ok(body::Json(msg))
} else {
Err(StatusCode::NOT_FOUND)
Expand Down
5 changes: 2 additions & 3 deletions examples/multipart-form/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct Message {
}

async fn upload_file(
multipart_form: body::MultipartForm,
mut multipart_form: body::MultipartForm,
) -> Result<body::Json<Message>, StatusCode> {
// https://stackoverflow.com/questions/43424982/how-to-parse-multipart-forms-using-abonander-multipart-with-rocket
let mut message = Message {
Expand All @@ -24,8 +24,7 @@ async fn upload_file(
file: None,
};

let mut multipart = multipart_form.0;
multipart
multipart_form
.foreach_entry(|mut entry| match entry.headers.name.as_str() {
"file" => {
let mut vec = Vec::new();
Expand Down
49 changes: 49 additions & 0 deletions src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use http::status::StatusCode;
use multipart::server::Multipart;
use pin_utils::pin_mut;
use std::io::Cursor;
use std::ops::{Deref, DerefMut};

use crate::{Extract, IntoResponse, Request, Response, RouteMatch};

Expand Down Expand Up @@ -152,6 +153,19 @@ impl<S: 'static> Extract<S> for MultipartForm {
}
}

impl Deref for MultipartForm {
type Target = Multipart<Cursor<Vec<u8>>>;
fn deref(&self) -> &Multipart<Cursor<Vec<u8>>> {
&self.0
}
}

impl DerefMut for MultipartForm {
fn deref_mut(&mut self) -> &mut Multipart<Cursor<Vec<u8>>> {
&mut self.0
}
}

/// A wrapper for json (de)serialization of bodies.
///
/// This type is usable both as an extractor (argument to an endpoint) and as a response
Expand Down Expand Up @@ -185,6 +199,13 @@ impl<T: 'static + Send + serde::Serialize> IntoResponse for Json<T> {
}
}

impl<T> Deref for Json<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}

/// A wrapper for form encoded (application/x-www-form-urlencoded) (de)serialization of bodies.
///
/// This type is usable both as an extractor (argument to an endpoint) and as a response
Expand Down Expand Up @@ -221,6 +242,13 @@ impl<T: 'static + Send + serde::Serialize> IntoResponse for Form<T> {
}
}

impl<T> Deref for Form<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}

pub struct Str(pub String);

impl<S: 'static> Extract<S> for Str {
Expand All @@ -239,6 +267,13 @@ impl<S: 'static> Extract<S> for Str {
}
}

impl Deref for Str {
type Target = String;
fn deref(&self) -> &String {
&self.0
}
}

pub struct StrLossy(pub String);

impl<S: 'static> Extract<S> for StrLossy {
Expand All @@ -257,6 +292,13 @@ impl<S: 'static> Extract<S> for StrLossy {
}
}

impl Deref for StrLossy {
type Target = String;
fn deref(&self) -> &String {
&self.0
}
}

pub struct Bytes(pub Vec<u8>);

impl<S: 'static> Extract<S> for Bytes {
Expand All @@ -273,3 +315,10 @@ impl<S: 'static> Extract<S> for Bytes {
))
}
}

impl Deref for Bytes {
type Target = Vec<u8>;
fn deref(&self) -> &Vec<u8> {
&self.0
}
}
15 changes: 15 additions & 0 deletions src/head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! automatically parse out information from a request.
use futures::future;
use std::ops::Deref;
use std::sync::Arc;

use crate::{Extract, IntoResponse, Request, Response, RouteMatch};
Expand Down Expand Up @@ -58,6 +59,13 @@ impl Head {
/// as type `T`, failing with a `NOT_FOUND` response if the component fails to parse.
pub struct Path<T>(pub T);

impl<T> Deref for Path<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}

/// A key for storing the current component match in a request's `extensions`
struct PathIdx(usize);

Expand Down Expand Up @@ -86,6 +94,13 @@ pub trait NamedComponent: Send + 'static + std::str::FromStr {
/// parse or if multiple identically named components exist.
pub struct Named<T: NamedComponent>(pub T);

impl<T: NamedComponent> Deref for Named<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}

impl<T: NamedComponent, S: 'static> Extract<S> for Named<T> {
type Fut = future::Ready<Result<Self, Response>>;

Expand Down

0 comments on commit 9ae1f13

Please sign in to comment.