diff --git a/.gitignore b/.gitignore index 6310b55..088ba6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Generated by Cargo # will have compiled files and executables /target/ @@ -9,8 +8,3 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk -======= -/target -**/*.rs.bk -Cargo.lock ->>>>>>> Initial commit diff --git a/Cargo.toml b/Cargo.toml index 957466c..b8fd647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,8 @@ members = ["http-service-hyper", "http-service-mock"] bytes = "0.4.12" http = "0.1.17" +[dev-dependencies] +http-service-hyper = { path = "http-service-hyper", version = "0.1.1" } + [dependencies.futures-preview] version = "0.3.0-alpha.14" diff --git a/README.md b/README.md index 41cdb2b..10f3b59 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,116 @@ -# http-service +

http-service

+
+ + Types and traits to help you implement your own HTTP server + +
-[![build status][1]][2] +
-Types and traits giving an interface between low-level http server implementations -and services that use them. The interface is based on the `std::futures` API. +
+ + + Crates.io version + + + + Build Status + + + + Download + + + + docs.rs docs + +
+ +
+

+ + API Docs + + | + + Chat + +

+
+ +
+ Built with ⛵ by The Rust Async Ecosystem WG +
+ +## About +The crate `http-service` provides the necessary types and traits to implement your own HTTP Server. It uses `hyper` for the lower level TCP abstraction. + +You can use the workspace member [`http-service-hyper`](https://crates.io/crates/http-service-hyper) to run your HTTP Server via `http_service_hyper::serve(HTTP_SERVICE, ADDRESS);` + +This crate uses the latest [Futures](https://github.com/rust-lang-nursery/futures-rs) preview, and therefore needs to be run on Rust Nightly. + +## Examples + +**Cargo.toml** +``` +[dependencies] +http-service = "0.1.5" +futures-preview = "0.3.0-alpha.14" + +[dependencies.http-service-hyper] +version = "0.1.1" +``` + +**main.rs** +```rust +#![feature(futures_api, async_await, await_macro, existential_type)] + +use futures::future::{self, FutureObj}; +use http_service::{HttpService, Response}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +struct Server { + message: Vec, +} + +impl Server { + fn create(message: Vec) -> Server { + Server { message } + } + + pub fn run(s: Server) { + let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + http_service_hyper::run(s, a); + } +} + +impl HttpService for Server { + type Connection = (); + type ConnectionFuture = future::Ready>; + type Fut = FutureObj<'static, Result>; + + fn connect(&self) -> Self::ConnectionFuture { + future::ok(()) + } + + fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut { + let message = self.message.clone(); + FutureObj::new(Box::new(async move { + Ok(Response::new(http_service::Body::from(message))) + })) + } +} + +fn main() { + let s = Server::create(String::from("Hello, World").into_bytes()); + Server::run(s); +} +``` ## License [MIT](./LICENSE-MIT) OR [Apache-2.0](./LICENSE-APACHE) - -[1]: https://img.shields.io/travis/rust-net-web/http-service.svg?style=flat-square -[2]: https://travis-ci.org/rust-net-web/http-service diff --git a/examples/simple_response.rs b/examples/simple_response.rs new file mode 100644 index 0000000..f519eec --- /dev/null +++ b/examples/simple_response.rs @@ -0,0 +1,42 @@ +#![feature(futures_api, async_await, await_macro, existential_type)] + +use futures::future::{self, FutureObj}; +use http_service::{HttpService, Response}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +struct Server { + message: Vec, +} + +impl Server { + fn create(message: Vec) -> Server { + Server { message } + } + + pub fn run(s: Server) { + let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); + http_service_hyper::run(s, a); + } +} + +impl HttpService for Server { + type Connection = (); + type ConnectionFuture = future::Ready>; + type Fut = FutureObj<'static, Result>; + + fn connect(&self) -> Self::ConnectionFuture { + future::ok(()) + } + + fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut { + let message = self.message.clone(); + FutureObj::new(Box::new(async move { + Ok(Response::new(http_service::Body::from(message))) + })) + } +} + +fn main() { + let s = Server::create(String::from("Hello, World").into_bytes()); + Server::run(s); +} diff --git a/http-service-hyper/Cargo.toml b/http-service-hyper/Cargo.toml index 1ddc125..a2e1156 100644 --- a/http-service-hyper/Cargo.toml +++ b/http-service-hyper/Cargo.toml @@ -13,7 +13,7 @@ version = "0.1.1" [dependencies] http = "0.1" -http-service = "0.1.5" +http-service = { version = "0.1.5", path = ".." } hyper = "0.12.27" [dependencies.futures-preview] diff --git a/src/lib.rs b/src/lib.rs index 8289093..cdbffb2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,57 @@ //! Types and traits giving an interface between low-level http server implementations //! and services that use them. The interface is based on the `std::futures` API. +//! +//! ## Example +//! ```no_run, rust, ignore +//! #![feature(futures_api, async_await, await_macro, existential_type)] +//! +//! use futures::{ +//! future::{self, FutureObj}, +//! }; +//! use http_service::{HttpService, Response}; +//! use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +//! +//! struct Server { +//! message: Vec, +//! } +//! +//! impl Server { +//! fn create(message: Vec) -> Server { +//! Server { +//! message, +//! } +//! } +//! +//! pub fn run(s: Server) { +//! let a = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); +//! http_service_hyper::run(s, a); +//! } +//! } +//! +//! impl HttpService for Server { +//! type Connection = (); +//! type ConnectionFuture = future::Ready>; +//! type Fut = FutureObj<'static, Result>; +//! +//! fn connect(&self) -> Self::ConnectionFuture { +//! future::ok(()) +//! } +//! +//! fn respond(&self, _conn: &mut (), _req: http_service::Request) -> Self::Fut { +//! let message = self.message.clone(); +//! FutureObj::new(Box::new( +//! async move { +//! Ok(Response::new(http_service::Body::from(message))) +//! } +//! )) +//! } +//! } +//! +//! fn main() { +//! let s = Server::create(String::from("Hello, World").into_bytes()); +//! Server::run(s); +//! } +//! ``` #![forbid(future_incompatible, rust_2018_idioms)] #![deny(missing_debug_implementations, nonstandard_style)]