Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
DeltaManiac committed Nov 28, 2018
2 parents bdde7d3 + f7e084d commit 80e35bd
Show file tree
Hide file tree
Showing 19 changed files with 243 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: rust
rust:
- nightly
- nightly-2018-11-24

before_script: |
rustup component add rustfmt-preview clippy-preview
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ features = ["compat"]
version = "0.3.0-alpha.9"

[dev-dependencies]
juniper = "0.10.0"
juniper = "0.10.0"
basic-cookies = "0.1.2"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ Read about the design here:
[MIT](./LICENSE-MIT) OR [Apache-2.0](./LICENSE-APACHE)

[1]: https://img.shields.io/travis/rust-net-web/tide.svg?style=flat-square
[2]: https://travis-ci.org/yoshuawuyts/tide
[2]: https://travis-ci.org/rust-net-web/tide
22 changes: 13 additions & 9 deletions examples/body_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,43 @@ 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
}

fn main() {
let mut app = tide::App::new(());

app.at("/echo/string").post(echo_string);
app.at("/echo/string_lossy").post(echo_string_lossy);
app.at("/echo/vec").post(echo_vec);
app.at("/echo/json").post(echo_json);
app.at("/echo/form").post(echo_form);
app.serve("127.0.0.1:8000");

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
40 changes: 40 additions & 0 deletions examples/computed_values.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![feature(async_await, futures_api)]
extern crate basic_cookies;

use basic_cookies::Cookie;
use std::collections::HashMap;
use tide::{Compute, Computed, Request};

#[derive(Clone, Debug)]
struct Cookies {
content: HashMap<String, String>,
}

impl Compute for Cookies {
fn compute_fresh(req: &mut Request) -> Self {
let content = if let Some(raw_cookies) = req.headers().get("Cookie") {
Cookie::parse(raw_cookies.to_str().unwrap())
.unwrap()
.iter()
.map(|c| (c.get_name().into(), c.get_value().into()))
.collect()
} else {
HashMap::new()
};

Cookies { content }
}
}

async fn hello_cookies(Computed(cookies): Computed<Cookies>) -> String {
format!("hello cookies: {:?}", cookies)
}

fn main() {
let mut app = tide::App::new(());
app.at("/").get(hello_cookies);

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
7 changes: 5 additions & 2 deletions examples/default_headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ fn main() {
app.middleware(
DefaultHeaders::new()
.header("X-Version", "1.0.0")
.header("X-Servier", "Tide"),
.header("X-Server", "Tide"),
);

app.at("/").get(async || "Hello, world!");
app.serve("127.0.0.1:7878")

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
7 changes: 4 additions & 3 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 All @@ -71,5 +70,7 @@ fn main() {

app.at("/graphql").post(handle_graphql);

app.serve("127.0.0.1:7878");
let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
5 changes: 4 additions & 1 deletion examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
fn main() {
let mut app = tide::App::new(());
app.at("/").get(async || "Hello, world!");
app.serve("127.0.0.1:7878")

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
10 changes: 6 additions & 4 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 All @@ -81,5 +81,7 @@ fn main() {
app.at("/message/{}").get(get_message);
app.at("/message/{}").post(set_message);

app.serve("127.0.0.1:7878");
let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
13 changes: 7 additions & 6 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 Expand Up @@ -66,9 +65,11 @@ fn main() {

app.at("/upload_file").post(upload_file);

app.serve("127.0.0.1:7878");
let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}

// Test with:
// curl -X POST http://localhost:7878/upload_file -H 'content-type: multipart/form-data' -F file=@examples/multipart-form/test.txt
// curl -X POST http://localhost:7878/upload_file -H 'content-type: multipart/form-data' -F key1=v1, -F key2=v2
// curl -X POST http://localhost:8000/upload_file -H 'content-type: multipart/form-data' -F file=@examples/multipart-form/test.txt
// curl -X POST http://localhost:8000/upload_file -H 'content-type: multipart/form-data' -F key1=v1, -F key2=v2
5 changes: 4 additions & 1 deletion examples/named_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ async fn add_two(Named(number): Named<Number>) -> String {
fn main() {
let mut app = tide::App::new(());
app.at("add_two/{num}").get(add_two);
app.serve("127.0.0.1:8000");

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
5 changes: 4 additions & 1 deletion examples/simple_nested_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ fn build_add_two<Data: Clone + Send + Sync + 'static>(router: &mut Router<Data>)
fn main() {
let mut app = tide::App::new(());
app.at("add_two").nest(build_add_two);
app.serve("127.0.0.1:8000");

let address = "127.0.0.1:8000".to_owned();
println!("Server is listening on http://{}", address);
app.serve(address);
}
1 change: 1 addition & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl<Data: Clone + Send + Sync + 'static> App<Data> {
}

/// Add a new resource at `path`.
/// See [Router.at](struct.Router.html#method.at) for details.
pub fn at<'a>(&'a mut self, path: &'a str) -> Resource<'a, Data> {
self.router.at(path)
}
Expand Down
79 changes: 79 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,19 @@ 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
}
}

impl<T> DerefMut for Json<T> {
fn deref_mut(&mut self) -> &mut T {
&mut 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 +248,19 @@ 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
}
}

impl<T> DerefMut for Form<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}

pub struct Str(pub String);

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

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

impl DerefMut for Str {
fn deref_mut(&mut self) -> &mut String {
&mut self.0
}
}

pub struct StrLossy(pub String);

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

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

impl DerefMut for StrLossy {
fn deref_mut(&mut self) -> &mut String {
&mut self.0
}
}

pub struct Bytes(pub Vec<u8>);

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

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

impl DerefMut for Bytes {
fn deref_mut(&mut self) -> &mut Vec<u8> {
&mut self.0
}
}
Loading

0 comments on commit 80e35bd

Please sign in to comment.