Open carllerche opened 5 years ago
Here are some thoughts about what using a macro might look like:
use futures::Stream;
struct MyGreeter;
impl MyGreeter {
fn new() -> MyGreeter {
MyGreeter
}
}
// Includes code generated from the `.proto` service and message definition.
include_proto!();
// For this to work, the `helloworld` module (generated by `include_proto!`)
// must be in scope. The macro will impl the `helloworld::Greeter` trait.
#[grpc(service = "helloworld.Greeter")]
impl MyGreeter {
fn say_hello(&self, request: HelloRequest) -> impl Future<Item = HelloReply> {
println!("HELLO; {:?}", request);
}
// The macro supports the following return types:
//
// -> impl Stream<Item = HelloReply>
// -> impl Future<Item = impl Stream<Item = HelloReply>>
// -> impl Future<Item = Response<impl Stream<Item = HelloReply>>>
// -> MyFuture
// -> impl Future<Item = MyStream>
// -> impl Future<Item = Response<MyStream>>
//
// # Wish list
//
// The macro knows what the item type should be and the error type does not
// matter as it gets mapped to an internal error. It would be nice if the
// return type could be simplified to:
//
// -> impl Future
// -> impl Stream
//
// This *should* be possible.
fn streaming_hello<S>(&self, request: S) -> impl Stream
where S: Stream<Item = HelloRequest>
{
unimplemented!();
}
}
@carllerche As impl
syntax is not supported in trait, do you means we should take input TokenStream like:
#[grpc(service = "helloworld.Greeter")]
impl MyGreeter {
fn say_hello(&self, request: HelloRequest) -> impl Future<Item = HelloReply> {
println!("HELLO; {:?}", request);
}
}
and get output TokenStream like:
impl helloworld::Greeter for MyGreeter {
fn say_hello<F: Future<Item = HelloReply>>(&self, request: HelloRequest) -> F {
println!("HELLO; {:?}", request);
}
}
?
@Hexilee The macro would have to translate impl
syntax -> Box<Future>
. This is what tower-web does
Tower gRPC provides a gRPC client / server implementation on top of the Tokio stack. Currently, the server API is tedious to use and has some limitations. The goal for the project is to implement a procedural macro to remove the boilerplate when defining gRPC server services. Also, a routing layer should be implemented in order to allow multiple gRPC services to respond on the same socket.
Expected outcomes
Skills
Difficulty level
Medium