Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove State and for<'a> as requirements from Middleware and Request #895

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
43a0c7f
Update response extensions to match request methods
nyxtom Jul 10, 2022
dd98a40
Move Request<State> generics to ext and trait
nyxtom Jul 15, 2022
d9a1514
Remove state from next/middleware layer
nyxtom Jul 15, 2022
5e16019
Update docs on request state
nyxtom Jul 15, 2022
4f77500
Update readme to exclude request state
nyxtom Jul 15, 2022
f607e07
Fix tests on disallowed primitive states
nyxtom Jul 15, 2022
49d7a6d
Fix warning on symetrical boolean nonminimal bool
nyxtom Jul 15, 2022
ff5f57e
Update Next to use cursors with Arc references
nyxtom Jul 16, 2022
b19de6f
Add support for impl Middleware to allow closure middleware
nyxtom Jul 16, 2022
41afeb9
Add support for impl Middleware in routes
nyxtom Jul 16, 2022
ac0abd3
Erase type on server state and place in Arc<State> any hashmap
nyxtom Jul 18, 2022
1dfecae
Update handle_unix to remove unused lifetime
nyxtom Jul 18, 2022
74a25a1
Refactor state into state middleware with request/response extensions
nyxtom Jul 18, 2022
5c1bb1b
Add response state function when expecting state middleware
nyxtom Jul 18, 2022
b96d774
Fix import on graphql example
nyxtom Jul 18, 2022
d101601
Cleanup request/response clippy
nyxtom Jul 18, 2022
dc75e00
Add back primitive state test in nested
nyxtom Jul 18, 2022
e21b4ed
Refactor selection/routing to just use Next as an endpoint
nyxtom Jul 19, 2022
2e314ff
Remove hashbrown dependency
nyxtom Jul 19, 2022
b8ba6c9
Re-enable log start on tests/examples
nyxtom Jul 19, 2022
1f6e5e9
Merge branch 'main' into patch-state-request
nyxtom Jul 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ async fn main() -> tide::Result<()> {
Ok(())
}

async fn order_shoes(mut req: Request<()>) -> tide::Result {
async fn order_shoes(mut req: Request) -> tide::Result {
let Animal { name, legs } = req.body_json().await?;
Ok(format!("Hello, {}! I've put in an order for {} shoes", name, legs).into())
}
Expand Down
2 changes: 1 addition & 1 deletion examples/concurrent_listeners.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ async fn main() -> Result<(), std::io::Error> {
let mut app = tide::new();
app.with(tide::log::LogMiddleware::new());

app.at("/").get(|request: Request<_>| async move {
app.at("/").get(|request: Request| async move {
Ok(format!(
"Hi! You reached this app through: {}",
request.local_addr().unwrap_or("an unknown port")
Expand Down
6 changes: 3 additions & 3 deletions examples/cookies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ use tide::{Request, Response, StatusCode};

/// Tide will use the the `Cookies`'s `Extract` implementation to build this parameter.
///
async fn retrieve_cookie(req: Request<()>) -> tide::Result<String> {
async fn retrieve_cookie(req: Request) -> tide::Result<String> {
Ok(format!("hello cookies: {:?}", req.cookie("hello").unwrap()))
}

async fn insert_cookie(_req: Request<()>) -> tide::Result {
async fn insert_cookie(_req: Request) -> tide::Result {
let mut res = Response::new(StatusCode::Ok);
res.insert_cookie(Cookie::new("hello", "world"));
Ok(res)
}

async fn remove_cookie(_req: Request<()>) -> tide::Result {
async fn remove_cookie(_req: Request) -> tide::Result {
let mut res = Response::new(StatusCode::Ok);
res.remove_cookie(Cookie::named("hello"));
Ok(res)
Expand Down
2 changes: 1 addition & 1 deletion examples/error_handling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async fn main() -> Result<()> {
}));

app.at("/")
.get(|_req: Request<_>| async { Ok(Body::from_file("./does-not-exist").await?) });
.get(|_req: Request| async { Ok(Body::from_file("./does-not-exist").await?) });

app.listen("127.0.0.1:8080").await?;

Expand Down
2 changes: 1 addition & 1 deletion examples/fib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn fib(n: usize) -> usize {
}
}

async fn fibsum(req: Request<()>) -> tide::Result<String> {
async fn fibsum(req: Request) -> tide::Result<String> {
use std::time::Instant;
let n: usize = req.param("n")?.parse().unwrap_or(0);
// Start a stopwatch
Expand Down
10 changes: 5 additions & 5 deletions examples/graphql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::{Arc, RwLock};

use juniper::{http::graphiql, http::GraphQLRequest, RootNode};
use lazy_static::lazy_static;
use tide::{http::mime, Body, Redirect, Request, Response, Server, StatusCode};
use tide::{http::mime, Body, Redirect, Request, Response, StatusCode};

#[derive(Clone)]
struct User {
Expand Down Expand Up @@ -74,9 +74,9 @@ lazy_static! {
static ref SCHEMA: Schema = Schema::new(QueryRoot {}, MutationRoot {});
}

async fn handle_graphql(mut request: Request<State>) -> tide::Result {
async fn handle_graphql(mut request: Request) -> tide::Result {
let query: GraphQLRequest = request.body_json().await?;
let response = query.execute(&SCHEMA, request.state());
let response = query.execute(&SCHEMA, request.state::<State>());
let status = if response.is_ok() {
StatusCode::Ok
} else {
Expand All @@ -88,15 +88,15 @@ async fn handle_graphql(mut request: Request<State>) -> tide::Result {
.build())
}

async fn handle_graphiql(_: Request<State>) -> tide::Result<impl Into<Response>> {
async fn handle_graphiql(_: Request) -> tide::Result<impl Into<Response>> {
Ok(Response::builder(200)
.body(graphiql::graphiql_source("/graphql"))
.content_type(mime::HTML))
}

#[async_std::main]
async fn main() -> std::io::Result<()> {
let mut app = Server::with_state(State {
let mut app = tide::with_state(State {
users: Arc::new(RwLock::new(Vec::new())),
});
app.at("/").get(Redirect::permanent("/graphiql"));
Expand Down
2 changes: 1 addition & 1 deletion examples/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async fn main() -> tide::Result<()> {
let mut app = tide::new();
app.with(tide::log::LogMiddleware::new());

app.at("/submit").post(|mut req: Request<()>| async move {
app.at("/submit").post(|mut req: Request| async move {
let cat: Cat = req.body_json().await?;
println!("cat name: {}", cat.name);

Expand Down
37 changes: 15 additions & 22 deletions examples/middleware.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

Expand All @@ -26,22 +24,17 @@ impl UserDatabase {
// This is an example of a function middleware that uses the
// application state. Because it depends on a specific request state,
// it would likely be closely tied to a specific application
fn user_loader<'a>(
mut request: Request<UserDatabase>,
next: Next<'a, UserDatabase>,
) -> Pin<Box<dyn Future<Output = Result> + Send + 'a>> {
Box::pin(async {
if let Some(user) = request.state().find_user().await {
trace!("user loaded", {user: user.name});
request.set_ext(user);
Ok(next.run(request).await)
// this middleware only needs to run before the endpoint, so
// it just passes through the result of Next
} else {
// do not run endpoints, we could not find a user
Ok(Response::new(StatusCode::Unauthorized))
}
})
async fn user_loader(mut request: Request, next: Next) -> Result {
if let Some(user) = request.state::<UserDatabase>().find_user().await {
trace!("user loaded", {user: user.name});
request.set_ext(user);
Ok(next.run(request).await)
// this middleware only needs to run before the endpoint, so
// it just passes through the result of Next
} else {
// do not run endpoints, we could not find a user
Ok(Response::new(StatusCode::Unauthorized))
}
}

// This is an example of middleware that keeps its own state and could
Expand All @@ -62,8 +55,8 @@ impl RequestCounterMiddleware {
struct RequestCount(usize);

#[tide::utils::async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for RequestCounterMiddleware {
async fn handle(&self, mut req: Request<State>, next: Next<'_, State>) -> Result {
impl Middleware for RequestCounterMiddleware {
async fn handle(&self, mut req: Request, next: Next) -> Result {
let count = self.requests_counted.fetch_add(1, Ordering::Relaxed);
trace!("request counter", { count: count });
req.set_ext(RequestCount(count));
Expand Down Expand Up @@ -115,12 +108,12 @@ async fn main() -> Result<()> {

app.with(user_loader);
app.with(RequestCounterMiddleware::new(0));
app.with(Before(|mut request: Request<UserDatabase>| async move {
app.with(Before(|mut request: Request| async move {
request.set_ext(std::time::Instant::now());
request
}));

app.at("/").get(|req: Request<_>| async move {
app.at("/").get(|req: Request| async move {
let count: &RequestCount = req.ext().unwrap();
let user: &User = req.ext().unwrap();

Expand Down
13 changes: 6 additions & 7 deletions examples/sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,23 @@ async fn main() -> Result<(), std::io::Error> {
));

app.with(tide::utils::Before(
|mut request: tide::Request<()>| async move {
|mut request: tide::Request| async move {
let session = request.session_mut();
let visits: usize = session.get("visits").unwrap_or_default();
session.insert("visits", visits + 1).unwrap();
request
},
));

app.at("/").get(|req: tide::Request<()>| async move {
app.at("/").get(|req: tide::Request| async move {
let visits: usize = req.session().get("visits").unwrap();
Ok(format!("you have visited this website {} times", visits))
});

app.at("/reset")
.get(|mut req: tide::Request<()>| async move {
req.session_mut().destroy();
Ok(tide::Redirect::new("/"))
});
app.at("/reset").get(|mut req: tide::Request| async move {
req.session_mut().destroy();
Ok(tide::Redirect::new("/"))
});

app.listen("127.0.0.1:8080").await?;

Expand Down
8 changes: 4 additions & 4 deletions examples/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ async fn main() -> tide::Result<()> {
femme::start();
let mut app = tide::with_state(State::new());
app.with(tide::log::LogMiddleware::new());
app.at("/").get(|req: tide::Request<State>| async move {
let state = req.state();
app.at("/").get(|req: tide::Request| async move {
let state = req.state::<State>();
let value = state.value.load(Ordering::Relaxed);
Ok(format!("{}\n", value))
});
app.at("/inc").get(|req: tide::Request<State>| async move {
let state = req.state();
app.at("/inc").get(|req: tide::Request| async move {
let state = req.state::<State>();
let value = state.value.fetch_add(1, Ordering::Relaxed) + 1;
Ok(format!("{}\n", value))
});
Expand Down
9 changes: 5 additions & 4 deletions examples/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ async fn main() -> Result<(), IoError> {
// $ curl localhost:8080/README.md # this reads the file from the same temp directory

app.at(":file")
.put(|req: Request<TempDirState>| async move {
.put(|req: Request| async move {
let path = req.param("file")?;
let fs_path = req.state().path().join(path);
let state = req.state::<TempDirState>();
let fs_path = state.path().join(path);

let file = OpenOptions::new()
.create(true)
Expand All @@ -56,9 +57,9 @@ async fn main() -> Result<(), IoError> {

Ok(json!({ "bytes": bytes_written }))
})
.get(|req: Request<TempDirState>| async move {
.get(|req: Request| async move {
let path = req.param("file")?;
let fs_path = req.state().path().join(path);
let fs_path = req.state::<TempDirState>().path().join(path);

if let Ok(body) = Body::from_file(fs_path).await {
Ok(body.into())
Expand Down
8 changes: 4 additions & 4 deletions src/cookies/middleware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::sync::{Arc, RwLock};
/// # use tide::{Request, Response, StatusCode};
/// # use tide::http::cookies::Cookie;
/// let mut app = tide::Server::new();
/// app.at("/get").get(|req: Request<()>| async move {
/// app.at("/get").get(|req: Request| async move {
/// Ok(req.cookie("testCookie").unwrap().value().to_string())
/// });
/// app.at("/set").get(|_| async {
Expand All @@ -35,8 +35,8 @@ impl CookiesMiddleware {
}

#[async_trait]
impl<State: Clone + Send + Sync + 'static> Middleware<State> for CookiesMiddleware {
async fn handle(&self, mut ctx: Request<State>, next: Next<'_, State>) -> crate::Result {
impl Middleware for CookiesMiddleware {
async fn handle(&self, mut ctx: Request, next: Next) -> crate::Result {
let cookie_jar = if let Some(cookie_data) = ctx.ext::<CookieData>() {
cookie_data.content.clone()
} else {
Expand Down Expand Up @@ -112,7 +112,7 @@ impl LazyJar {
}

impl CookieData {
pub(crate) fn from_request<S>(req: &Request<S>) -> Self {
pub(crate) fn from_request(req: &Request) -> Self {
let jar = if let Some(cookie_headers) = req.header(&headers::COOKIE) {
let mut jar = CookieJar::new();
for cookie_header in cookie_headers {
Expand Down
Loading