Inital pass at route guide
This commit is contained in:
+115
-7
@@ -126,12 +126,30 @@ fn generate_methods(service: &ServiceDef) -> TokenStream {
|
||||
);
|
||||
let method_path = Lit::Str(LitStr::new(&path, Span::call_site()));
|
||||
|
||||
let method_stream = generate_unary(
|
||||
method,
|
||||
ident.clone(),
|
||||
service.name.clone(),
|
||||
&service.proto_path,
|
||||
);
|
||||
let method_stream = match (method.client_streaming, method.server_streaming) {
|
||||
(false, false) => generate_unary(
|
||||
method,
|
||||
ident.clone(),
|
||||
service.name.clone(),
|
||||
&service.proto_path,
|
||||
),
|
||||
|
||||
(false, true) => generate_server_streaming(
|
||||
method,
|
||||
ident.clone(),
|
||||
service.name.clone(),
|
||||
&service.proto_path,
|
||||
),
|
||||
|
||||
(true, false) => generate_client_streaming(
|
||||
method,
|
||||
ident.clone(),
|
||||
service.name.clone(),
|
||||
&service.proto_path,
|
||||
),
|
||||
|
||||
_ => unimplemented!("method type"),
|
||||
};
|
||||
|
||||
let method = quote! {
|
||||
#method_path => {
|
||||
@@ -160,7 +178,7 @@ fn generate_unary(
|
||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||
|
||||
impl tonic::server::UnaryService<#request> for #service_ident {
|
||||
type Response =#response;
|
||||
type Response = #response;
|
||||
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
|
||||
|
||||
fn call(&mut self, request: tonic::Request<#request>) -> Self::Future {
|
||||
@@ -184,3 +202,93 @@ fn generate_unary(
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_server_streaming(
|
||||
method: &Method,
|
||||
method_ident: Ident,
|
||||
service_impl: Path,
|
||||
proto_path: &str,
|
||||
) -> TokenStream {
|
||||
let service_ident = Ident::new(&method.proto_name, Span::call_site());
|
||||
|
||||
let request: Path = syn::parse_str(&format!("{}::{}", proto_path, method.input_type)).unwrap();
|
||||
let response: Path =
|
||||
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||
|
||||
// TODO: parse response stream type, if it is a concrete type then use that
|
||||
// as the ResponseStream type, if it is a impl Trait then we need to box.
|
||||
quote! {
|
||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||
|
||||
impl tonic::server::ServerStreamingService<#request> for #service_ident {
|
||||
type Response = #response;
|
||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<Self::Response, Status>> + Send>>;
|
||||
type Future = BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>;
|
||||
|
||||
fn call(&mut self, request: tonic::Request<#request>) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
inner.#method_ident(request).await
|
||||
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let method = #service_ident(inner);
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = tonic::server::Grpc::new(codec);
|
||||
let res = grpc.server_streaming(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_client_streaming(
|
||||
method: &Method,
|
||||
method_ident: Ident,
|
||||
service_impl: Path,
|
||||
proto_path: &str,
|
||||
) -> TokenStream {
|
||||
let service_ident = Ident::new(&method.proto_name, Span::call_site());
|
||||
|
||||
let request: Path = syn::parse_str(&format!("{}::{}", proto_path, method.input_type)).unwrap();
|
||||
let response: Path =
|
||||
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||
|
||||
// TODO: parse response stream type, if it is a concrete type then use that
|
||||
// as the ResponseStream type, if it is a impl Trait then we need to box.
|
||||
quote! {
|
||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||
|
||||
impl<S> tonic::server::ClientStreamingService<S> for #service_ident
|
||||
where S: Stream<Item = Result<#request, Status>> + Unpin + Send + 'static {
|
||||
type Response = #response;
|
||||
type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>;
|
||||
|
||||
fn call(&mut self, request: tonic::Request<S>) -> Self::Future {
|
||||
let inner = self.0.clone();
|
||||
let fut = async move {
|
||||
inner.#method_ident(request).await
|
||||
|
||||
};
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
let inner = self.inner.clone();
|
||||
let fut = async move {
|
||||
let method = #service_ident(inner);
|
||||
let codec = tonic::codec::ProstCodec::new();
|
||||
let mut grpc = tonic::server::Grpc::new(codec);
|
||||
let res = grpc.client_streaming(method, req).await;
|
||||
Ok(res)
|
||||
};
|
||||
|
||||
Box::pin(fut)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user