diff --git a/README.md b/README.md index 529ea28..0cae376 100644 --- a/README.md +++ b/README.md @@ -31,16 +31,12 @@ works with the community-backed library serde: any serde-serializable type can b arguments to tarpc fns. ## Usage -**NB**: *this example is for master. Are you looking for other -[versions](https://docs.rs/tarpc)?* - Add to your `Cargo.toml` dependencies: ```toml -tarpc = "0.13.0" +tarpc = "0.14.0" ``` - The `service!` macro expands to a collection of items that form an rpc service. In the above example, the macro is called within the `hello_service` module. This module will contain a `Client` stub and `Service` trait. There is @@ -48,34 +44,29 @@ These generated types make it easy and ergonomic to write servers without dealin directly. Simply implement one of the generated traits, and you're off to the races! -## Example: +## Example Here's a small service. ```rust -#![feature( - futures_api, - pin, - arbitrary_self_types, - await_macro, - async_await, - proc_macro_hygiene, -)] +#![feature(futures_api, pin, arbitrary_self_types, await_macro, async_await, proc_macro_hygiene)] + use futures::{ + compat::TokioDefaultSpawner, future::{self, Ready}, prelude::*, }; -use rpc::{ +use tarpc::{ client, context, - server::{self, Handler, Server}, + server::{self, Handler}, }; use std::io; // This is the service definition. It looks a lot like a trait definition. // It defines one RPC, hello, which takes one arg, name, and returns a String. - tarpc::service! { + /// Returns a greeting for name. rpc hello(name: String) -> String; } @@ -90,7 +81,7 @@ impl Service for HelloServer { type HelloFut = Ready; - fn hello(&self, _: context::Context, name: String) -> Self::HelloFut { + fn hello(self, _: context::Context, name: String) -> Self::HelloFut { future::ready(format!("Hello, {}!", name)) } } @@ -102,12 +93,12 @@ async fn run() -> io::Result<()> { let addr = transport.local_addr(); // The server is configured with the defaults. - let server = Server::new(server::Config::default()) + let server = server::new(server::Config::default()) // Server can listen on any type that implements the Transport trait. .incoming(transport) // Close the stream after the client connects .take(1) - // serve is generated by the tarpc::service! macro. It takes as input any type implementing + // serve is generated by the service! macro. It takes as input any type implementing // the generated Service trait. .respond_with(serve(HelloServer)); @@ -115,12 +106,12 @@ async fn run() -> io::Result<()> { let transport = await!(bincode_transport::connect(&addr))?; - // new_stub is generated by the tarpc::service! macro. Like Server, it takes a config and any + // new_stub is generated by the service! macro. Like Server, it takes a config and any // Transport as input, and returns a Client, also generated by the macro. // by the service mcro. let mut client = await!(new_stub(client::Config::default(), transport))?; - // The client has an RPC method for each RPC defined in tarpc::service!. It takes the same args + // The client has an RPC method for each RPC defined in service!. It takes the same args // as defined, with the addition of a Context, which is always the first arg. The Context // specifies a deadline and trace information which can be helpful in debugging requests. let hello = await!(client.hello(context::current(), "Stim".to_string()))?; @@ -131,8 +122,8 @@ async fn run() -> io::Result<()> { } fn main() { - tokio::run( - run() + tarpc::init(TokioDefaultSpawner); + tokio::run(run() .map_err(|e| eprintln!("Oh no: {}", e)) .boxed() .compat(), diff --git a/tarpc/src/lib.rs b/tarpc/src/lib.rs index 5e01a09..7857534 100644 --- a/tarpc/src/lib.rs +++ b/tarpc/src/lib.rs @@ -4,116 +4,9 @@ // license that can be found in the LICENSE file or at // https://opensource.org/licenses/MIT. -//! tarpc is an RPC framework for rust with a focus on ease of use. Defining a -//! service can be done in just a few lines of code, and most of the boilerplate of -//! writing a server is taken care of for you. -//! -//! ## What is an RPC framework? -//! "RPC" stands for "Remote Procedure Call," a function call where the work of -//! producing the return value is being done somewhere else. When an rpc function is -//! invoked, behind the scenes the function contacts some other process somewhere -//! and asks them to evaluate the function instead. The original function then -//! returns the value produced by the other process. -//! -//! RPC frameworks are a fundamental building block of most microservices-oriented -//! architectures. Two well-known ones are [gRPC](http://www.grpc.io) and -//! [Cap'n Proto](https://capnproto.org/). -//! -//! tarpc differentiates itself from other RPC frameworks by defining the schema in code, -//! rather than in a separate language such as .proto. This means there's no separate compilation -//! process, and no cognitive context switching between different languages. Additionally, it -//! works with the community-backed library serde: any serde-serializable type can be used as -//! arguments to tarpc fns. -//! -//! ## Example -//! -//! Here's a small service. -//! -//! ```rust -//! #![feature(futures_api, pin, arbitrary_self_types, await_macro, async_await, proc_macro_hygiene)] -//! -//! -//! use futures::{ -//! compat::TokioDefaultSpawner, -//! future::{self, Ready}, -//! prelude::*, -//! }; -//! use tarpc::{ -//! client, context, -//! server::{self, Handler}, -//! }; -//! use std::io; -//! -//! // This is the service definition. It looks a lot like a trait definition. -//! // It defines one RPC, hello, which takes one arg, name, and returns a String. -//! tarpc::service! { -//! /// Returns a greeting for name. -//! rpc hello(name: String) -> String; -//! } -//! -//! // This is the type that implements the generated Service trait. It is the business logic -//! // and is used to start the server. -//! #[derive(Clone)] -//! struct HelloServer; -//! -//! impl Service for HelloServer { -//! // Each defined rpc generates two items in the trait, a fn that serves the RPC, and -//! // an associated type representing the future output by the fn. -//! -//! type HelloFut = Ready; -//! -//! fn hello(&self, _: context::Context, name: String) -> Self::HelloFut { -//! future::ready(format!("Hello, {}!", name)) -//! } -//! } -//! -//! async fn run() -> io::Result<()> { -//! // bincode_transport is provided by the associated crate bincode-transport. It makes it easy -//! // to start up a serde-powered bincode serialization strategy over TCP. -//! let transport = bincode_transport::listen(&"0.0.0.0:0".parse().unwrap())?; -//! let addr = transport.local_addr(); -//! -//! // The server is configured with the defaults. -//! let server = server::new(server::Config::default()) -//! // Server can listen on any type that implements the Transport trait. -//! .incoming(transport) -//! // Close the stream after the client connects -//! .take(1) -//! // serve is generated by the service! macro. It takes as input any type implementing -//! // the generated Service trait. -//! .respond_with(serve(HelloServer)); -//! -//! tokio_executor::spawn(server.unit_error().boxed().compat()); -//! -//! let transport = await!(bincode_transport::connect(&addr))?; -//! -//! // new_stub is generated by the service! macro. Like Server, it takes a config and any -//! // Transport as input, and returns a Client, also generated by the macro. -//! // by the service mcro. -//! let mut client = await!(new_stub(client::Config::default(), transport))?; -//! -//! // The client has an RPC method for each RPC defined in service!. It takes the same args -//! // as defined, with the addition of a Context, which is always the first arg. The Context -//! // specifies a deadline and trace information which can be helpful in debugging requests. -//! let hello = await!(client.hello(context::current(), "Stim".to_string()))?; -//! -//! println!("{}", hello); -//! -//! Ok(()) -//! } -//! -//! fn main() { -//! tarpc::init(TokioDefaultSpawner); -//! tokio::run(run() -//! .map_err(|e| eprintln!("Oh no: {}", e)) -//! .boxed() -//! .compat(), -//! ); -//! } -//! ``` - +#![doc(include = "../../README.md")] #![deny(missing_docs, missing_debug_implementations)] -#![feature(async_await)] +#![feature(async_await, external_doc)] #![cfg_attr( test, feature(