-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Consider an IntoRequest
trait
#34
Comments
Hey! I'm fairly new to this project, but the library seems fantastic so far! This looks like a nice first issue. I was hoping to take a crack at it sometime this week or over the weekend if a PR is welcome. 😃 |
@ChetanBhasin I'm not sure if this is actually going to be easy, or even possible — I took a crack at it earlier, and ran into some issues with type inference. If you want to take a look at it, you may have more success than I did, but I just wanted to warn you. |
For this to work out, there would need to be two traits. Sketch: struct Request<T>(T);
trait Message: std::fmt::Display {}
impl Message for &'static str {}
trait IntoRequest {
type Message: Message;
fn into_request(self) -> Request<Self::Message>;
}
trait IntoStreamingRequest {
type Stream: Iterator<Item = Self::Message>;
type Message: Message;
fn into_streaming_request(self) -> Request<Self::Stream>;
}
impl<T: Message> IntoRequest for Request<T> {
type Message = T;
fn into_request(self) -> Self {
self
}
}
impl<T: Iterator> IntoStreamingRequest for Request<T> where T::Item: Message {
type Stream = T;
type Message = T::Item;
fn into_streaming_request(self) -> Self {
self
}
}
impl<T: Iterator> IntoStreamingRequest for T where T::Item: Message {
type Stream = T;
type Message = T::Item;
fn into_streaming_request(self) -> Request<Self> {
Request(self)
}
}
fn say_hello<T: IntoStreamingRequest<Message = &'static str>>(t: T) {
println!("== say hello");
for msg in t.into_streaming_request().0 {
println!(" + {}", msg);
}
}
fn main() {
say_hello(vec!["hello", "world"].into_iter());
say_hello(Request(vec!["hello", "world"].into_iter()));
} |
Oh, the solution of adding a separate trait for streaming requests is obvious in hindsight, nice! |
hyperium#34 properly implement TLS-1.3 shutdown behavior
Feature Request
Crates
tonic
Motivation
Currently, Tonic's
Client
API requires users to write code like this:The need to wrap the request struct in a
tonic::Request
is a minor ergonomics issue that could be surprising. This is admittedly a pretty minor papercut, but it seems like it would reduce some friction in the APIs that I suspect a new user is most likely to use (and make the basic examples seem simpler!)...Proposal
What do you think about changing the client API so that users could just write:
We could add a trait like this:
and generate impls for all the generated request messages, like
Then, we could change the generated RPC methods on the client to be like this:
We could add an impl of
IntoRequest
forRequest<T>
like this:which would allow users could still construct
tonic::Request
types if needed, such as when manually adding headers etc.Something similar could probably be done for response messages.
Alternatives
We could also consider using
From
andInto
here, rather than defining a newIntoRequest
trait. This is what I originally suggested in #1 (comment). Ideally, I think it would be better to use the stdlib traits where possible, rather than defining a new one. However, @LucioFranco says that this causes some issues with type inference which a new trait could possibly avoid.The text was updated successfully, but these errors were encountered: