Add easy connect method in codegen

This commit is contained in:
Lucio Franco
2019-09-21 14:21:28 -06:00
parent 5ded741eb6
commit 922e480cec
8 changed files with 74 additions and 20 deletions
+2
View File
@@ -14,4 +14,6 @@ proc-macro2 = "1.0"
[features]
default = ["transport"]
rustfmt = []
transport = []
+24
View File
@@ -7,11 +7,15 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream {
let service_ident = quote::format_ident!("{}Client", service.name);
let methods = generate_methods(service, proto);
let connect = generate_connect(&service_ident);
quote! {
pub struct #service_ident<T> {
inner: tonic::client::Grpc<T>,
}
#connect
impl<T> #service_ident<T>
where T: tonic::client::GrpcService<tonic::body::BoxBody>,
T::ResponseBody: Body + HttpBody + Send + 'static,
@@ -42,6 +46,26 @@ pub(crate) fn generate(service: &Service, proto: &str) -> TokenStream {
}
}
#[cfg(feature = "transport")]
fn generate_connect(service_ident: &syn::Ident) -> TokenStream {
quote! {
impl #service_ident<tonic::transport::Channel> {
pub fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error>
where
D: std::convert::TryInto<tonic::transport::Endpoint>,
D::Error: Into<StdError>,
{
tonic::transport::Channel::builder().build(dst).map(|c| Self::new(c))
}
}
}
}
#[cfg(not(feature = "transport"))]
fn generate_connect() -> TokenStream {
TokenStream::new()
}
fn generate_methods(service: &Service, proto: &str) -> TokenStream {
let mut stream = TokenStream::new();
+1 -7
View File
@@ -1,5 +1,3 @@
use tonic::transport::Channel;
pub mod hello_world {
include!(concat!(env!("OUT_DIR"), "/helloworld.rs"));
}
@@ -8,11 +6,7 @@ use hello_world::{client::GreeterClient, HelloRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let origin = vec![http::Uri::from_static("http://[::1]:50051").into()];
let svc = Channel::builder().balance_list(origin)?;
let mut client = GreeterClient::new(svc);
let mut client = GreeterClient::connect("http://[::1]:50051")?;
let request = tonic::Request::new(HelloRequest {
name: "hello".into(),
+2 -5
View File
@@ -2,7 +2,7 @@ use futures::TryStreamExt;
use route_guide::{Point, RouteNote};
use std::time::{Duration, Instant};
use tokio::timer::Interval;
use tonic::{transport::Channel, Request};
use tonic::Request;
mod route_guide {
include!(concat!(env!("OUT_DIR"), "/routeguide.rs"));
@@ -12,10 +12,7 @@ use route_guide::client::RouteGuideClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let origin = http::Uri::from_static("http://[::1]:10000");
let svc = Channel::builder().build(origin)?;
let mut client = RouteGuideClient::new(svc);
let mut client = RouteGuideClient::connect("http://[::1]:10000")?;
let start = Instant::now();
+1 -1
View File
@@ -1,5 +1,5 @@
use super::Decoder;
use crate::{metadata::MetadataMap, body::BoxBody, Code, Status};
use crate::{body::BoxBody, metadata::MetadataMap, Code, Status};
use bytes::{Buf, BufMut, Bytes, BytesMut, IntoBuf};
use futures_core::Stream;
use futures_util::{future, ready};
+2 -1
View File
@@ -1,7 +1,8 @@
use crate::{
body::BoxBody,
codec::{encode_server, Codec, Streaming},
server::{ClientStreamingService, ServerStreamingService, StreamingService, UnaryService},
body::BoxBody, Code, Request, Response, Status,
Code, Request, Response, Status,
};
use bytes::Bytes;
use futures_core::TryStream;
+6 -5
View File
@@ -7,6 +7,7 @@ use futures_util::try_future::{MapErr, TryFutureExt};
use http::Uri;
use hyper::{Request, Response};
use std::{
convert::TryInto,
fmt,
future::Future,
pin::Pin,
@@ -107,12 +108,12 @@ impl Builder {
pub fn build<T>(&mut self, uri: T) -> Result<Channel, super::Error>
where
Uri: http::HttpTryFrom<T>,
T: TryInto<Endpoint>,
T::Error: Into<crate::Error>,
{
let uri: Uri = match http::HttpTryFrom::try_from(uri) {
Ok(u) => u,
Err(e) => panic!("Invalid uri: {}", e.into()),
};
let uri = uri
.try_into()
.map_err(|e| super::Error::from((super::ErrorKind::Client, e.into())))?;
self.balance_list(vec![uri.into()])
}
+36 -1
View File
@@ -1,7 +1,7 @@
use super::{channel::Channel, tls::Cert};
use bytes::Bytes;
use http::uri::{InvalidUriBytes, Uri};
use std::time::Duration;
use std::{convert::TryFrom, time::Duration};
#[derive(Debug, Clone)]
pub struct Endpoint {
@@ -65,3 +65,38 @@ impl From<Uri> for Endpoint {
}
}
}
impl TryFrom<Bytes> for Endpoint {
type Error = InvalidUriBytes;
fn try_from(t: Bytes) -> Result<Self, Self::Error> {
Self::from_shared(t)
}
}
impl TryFrom<String> for Endpoint {
type Error = InvalidUriBytes;
fn try_from(t: String) -> Result<Self, Self::Error> {
Self::from_shared(t.into_bytes())
}
}
impl TryFrom<&'static str> for Endpoint {
type Error = Never;
fn try_from(t: &'static str) -> Result<Self, Self::Error> {
Ok(Self::from_static(t))
}
}
#[derive(Debug)]
pub enum Never {}
impl std::fmt::Display for Never {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match *self {}
}
}
impl std::error::Error for Never {}