diff --git a/examples/hello_world.rs b/examples/hello_world.rs new file mode 100644 index 00000000..4b169700 --- /dev/null +++ b/examples/hello_world.rs @@ -0,0 +1,33 @@ +use http::Request; +use hyper::Server; +use std::net::SocketAddr; +use tower::{make::Shared, ServiceBuilder}; +use tower_http::trace::TraceLayer; +use tower_web::{body::Body, response::Html, Error}; + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + + // build our application with some routes + let app = tower_web::app() + .at("/") + .get(handler) + // convert it into a `Service` + .into_service(); + + // add some middleware + let app = ServiceBuilder::new() + .layer(TraceLayer::new_for_http()) + .service(app); + + // run it with hyper + let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + tracing::debug!("listening on {}", addr); + let server = Server::bind(&addr).serve(Shared::new(app)); + server.await.unwrap(); +} + +async fn handler(_req: Request) -> Result, Error> { + Ok(Html("

Hello, World!

")) +} diff --git a/src/extract.rs b/src/extract.rs index b2270e84..4892016b 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -2,7 +2,6 @@ use crate::{body::Body, Error}; use bytes::Bytes; use futures_util::{future, ready}; use http::Request; -use http_body::Body as _; use pin_project::pin_project; use serde::de::DeserializeOwned; use std::{ diff --git a/src/lib.rs b/src/lib.rs index 50a813f1..ed3bda72 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -#![allow(unused_imports, dead_code)] - /* Improvements to make: @@ -13,27 +11,19 @@ Tests */ use self::{ - body::{Body, BoxBody}, - extract::FromRequest, - handler::{Handler, HandlerSvc}, - response::IntoResponse, + body::Body, routing::{EmptyRouter, RouteAt}, }; -use async_trait::async_trait; use bytes::Bytes; -use futures_util::{future, ready}; -use http::{header, HeaderValue, Method, Request, Response, StatusCode}; -use http_body::Body as _; +use futures_util::ready; +use http::Response; use pin_project::pin_project; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::{ - convert::Infallible, future::Future, - marker::PhantomData, pin::Pin, task::{Context, Poll}, }; -use tower::{BoxError, Layer, Service, ServiceExt}; +use tower::Service; pub mod body; pub mod extract; @@ -154,11 +144,15 @@ where mod tests { #![allow(warnings)] use super::*; + use crate::handler::Handler; + use http::{Method, Request, StatusCode}; use hyper::Server; + use serde::Deserialize; use std::time::Duration; use std::{fmt, net::SocketAddr, sync::Arc}; use tower::{ layer::util::Identity, make::Shared, service_fn, timeout::TimeoutLayer, ServiceBuilder, + ServiceExt, }; use tower_http::{ add_extension::AddExtensionLayer, diff --git a/src/response.rs b/src/response.rs index 5174b741..a0782384 100644 --- a/src/response.rs +++ b/src/response.rs @@ -92,6 +92,21 @@ where } } +pub struct Html(pub T); + +impl IntoResponse for Html +where + T: Into, +{ + fn into_response(self) -> Result, Error> { + let bytes = self.0.into(); + let mut res = Response::new(Body::from(bytes)); + res.headers_mut() + .insert(header::CONTENT_TYPE, HeaderValue::from_static("text/html")); + Ok(res) + } +} + #[derive(Debug, Copy, Clone)] pub struct Empty; diff --git a/src/routing.rs b/src/routing.rs index 47c0bdf8..6597b78a 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -14,7 +14,7 @@ use std::{ pin::Pin, task::{Context, Poll}, }; -use tower::{BoxError, Layer, Service}; +use tower::{BoxError, Service}; #[derive(Clone, Copy)] pub struct EmptyRouter(pub(crate) ()); @@ -398,12 +398,4 @@ mod tests { std::str::from_utf8(&route.spec).unwrap(), ); } - - fn route(method: Method, uri: &'static str) -> RouteSpec { - RouteSpec::new(method, uri) - } - - fn req(method: Method, uri: &str) -> Request<()> { - Request::builder().uri(uri).method(method).body(()).unwrap() - } }