Add easy connect method in codegen
This commit is contained in:
@@ -14,4 +14,6 @@ proc-macro2 = "1.0"
|
||||
|
||||
|
||||
[features]
|
||||
default = ["transport"]
|
||||
rustfmt = []
|
||||
transport = []
|
||||
|
||||
@@ -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,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,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,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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()])
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
Reference in New Issue
Block a user