More macro clean up
This commit is contained in:
+24
-107
@@ -15,118 +15,16 @@ pub fn server(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
let item = syn::parse_macro_input!(item as ItemImpl);
|
let item = syn::parse_macro_input!(item as ItemImpl);
|
||||||
let args = syn::parse_macro_input!(attr as AttributeArgs);
|
let args = syn::parse_macro_input!(attr as AttributeArgs);
|
||||||
|
|
||||||
let service = load_service(args);
|
let (service, proto_path) = load_service(args);
|
||||||
let service_def = service::parse_service_impl(item, service);
|
|
||||||
|
let service_def = service::parse_service_impl(item, service, proto_path);
|
||||||
let output = service::generate(service_def);
|
let output = service::generate(service_def);
|
||||||
|
|
||||||
original.extend(TokenStream::from(output));
|
original.extend(TokenStream::from(output));
|
||||||
original
|
original
|
||||||
|
|
||||||
// let mut original = item.clone();
|
|
||||||
// let ItemImpl { self_ty, items, .. } = syn::parse_macro_input!(item as ItemImpl);
|
|
||||||
|
|
||||||
// let mut m_ident = None;
|
|
||||||
// for item in items {
|
|
||||||
// if let ImplItem::Method(method) = item {
|
|
||||||
// // println!("{:?}", method);
|
|
||||||
|
|
||||||
// let ImplItemMethod { sig, .. } = method;
|
|
||||||
|
|
||||||
// if sig.asyncness.is_some() {
|
|
||||||
// let name = format!("{}", sig.ident);
|
|
||||||
|
|
||||||
// if let Some(_method) = service.methods.iter().find(|method| method.name == name) {
|
|
||||||
// // println!("found method!");
|
|
||||||
// m_ident = Some(sig.ident.clone());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let service_name = service.proto_name.clone();
|
|
||||||
|
|
||||||
// let ts = quote! {
|
|
||||||
// use tonic::_codegen;
|
|
||||||
// use proto::*;
|
|
||||||
|
|
||||||
// #[derive(Clone)]
|
|
||||||
// pub struct GrpcServer {
|
|
||||||
// inner: std::sync::Arc<#s>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl GrpcServer {
|
|
||||||
// fn new(t: #s) -> Self {
|
|
||||||
// Self { inner: std::sync::Arc::new(t) }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl _codegen::Service<()> for GrpcServer {
|
|
||||||
// type Response = Self;
|
|
||||||
// type Error = tonic::error::Never;
|
|
||||||
// type Future = _codegen::Ready<Result<Self::Response, Self::Error>>;
|
|
||||||
|
|
||||||
// fn poll_ready(&mut self, _cx: &mut _codegen::Context<'_>) -> _codegen::Poll<Result<(), Self::Error>> {
|
|
||||||
// std::task::Poll::Ready(Ok(()))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn call(&mut self, _: ()) -> Self::Future {
|
|
||||||
// _codegen::ok(self.clone())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl _codegen::Service<_codegen::http::Request<tower_h2::RecvBody>> for GrpcServer {
|
|
||||||
// type Response = _codegen::http::Response<tonic::body::BoxAsyncBody>;
|
|
||||||
// type Error = tonic::error::Never;
|
|
||||||
// type Future = _codegen::ResponseFuture2<Self::Response, Self::Error>;
|
|
||||||
|
|
||||||
// fn poll_ready(&mut self, _cx: &mut _codegen::Context<'_>) -> _codegen::Poll<Result<(), Self::Error>> {
|
|
||||||
// Ok(()).into()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn call(&mut self, request: _codegen::http::Request<tower_h2::RecvBody>) -> Self::Future {
|
|
||||||
// let inner = self.inner.clone();
|
|
||||||
|
|
||||||
// match request.uri().path() {
|
|
||||||
// "/helloworld.Greeter/SayHello" => {
|
|
||||||
// use tonic::_codegen::*;
|
|
||||||
// use tonic::*;
|
|
||||||
|
|
||||||
// pub struct SayHello(pub std::sync::Arc<#s>);
|
|
||||||
|
|
||||||
// impl tonic::server::UnaryService<HelloRequest> for SayHello {
|
|
||||||
// type Response = HelloReply;
|
|
||||||
// type Future = Pin<Box<dyn Future<Output = Result<Response<Self::Response>, Status>> + Send + 'static>>;
|
|
||||||
|
|
||||||
// fn call(&mut self, request: Request<HelloRequest>) -> Self::Future {
|
|
||||||
// let inner = self.0.clone();
|
|
||||||
// let fut = async move {
|
|
||||||
// inner.#m_ident(request).await
|
|
||||||
// };
|
|
||||||
// Box::pin(fut)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let inner = self.inner.clone();
|
|
||||||
|
|
||||||
// let fut = async move {
|
|
||||||
// let method = SayHello(inner);
|
|
||||||
// let codec = tonic::codec::ProstCodec::new();
|
|
||||||
// let mut grpc = tonic::server::Grpc::new(codec);
|
|
||||||
// let res = grpc.unary(method, request).await;
|
|
||||||
// Ok(res)
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Box::pin(fut)
|
|
||||||
// },
|
|
||||||
// _ => unimplemented!("use grpc unimplemented")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_service(attr: AttributeArgs) -> Service {
|
fn load_service(attr: AttributeArgs) -> (Service, String) {
|
||||||
use syn::{Lit, Meta, MetaNameValue, NestedMeta};
|
use syn::{Lit, Meta, MetaNameValue, NestedMeta};
|
||||||
|
|
||||||
let service = attr
|
let service = attr
|
||||||
@@ -147,14 +45,33 @@ fn load_service(attr: AttributeArgs) -> Service {
|
|||||||
None => panic!("expected a `service = \"package.Service\" attribute"),
|
None => panic!("expected a `service = \"package.Service\" attribute"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let service = attr
|
||||||
|
.iter()
|
||||||
|
.filter_map(|i| match i {
|
||||||
|
NestedMeta::Meta(Meta::NameValue(MetaNameValue { path, lit, .. }))
|
||||||
|
if path.segments.first().unwrap().ident == "proto" =>
|
||||||
|
{
|
||||||
|
Some(lit.clone())
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next();
|
||||||
|
|
||||||
|
let proto_path = match service {
|
||||||
|
Some(Lit::Str(s)) => s.value(),
|
||||||
|
Some(_) => panic!("expected a literal string"),
|
||||||
|
None => panic!("expected a `proto = \"my::proto::path\" attribute"),
|
||||||
|
};
|
||||||
|
|
||||||
let file = format!(
|
let file = format!(
|
||||||
"{}/{}.json",
|
"{}/{}.json",
|
||||||
std::env::var("OUT_DIR").unwrap(),
|
std::env::var("OUT_DIR").unwrap(),
|
||||||
service_name
|
service_name
|
||||||
);
|
);
|
||||||
let json = std::fs::read_to_string(file).unwrap();
|
let json = std::fs::read_to_string(file).unwrap();
|
||||||
|
let svc = serde_json::from_str(&json).unwrap();
|
||||||
|
|
||||||
serde_json::from_str(&json).unwrap()
|
(svc, proto_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A service descriptor.
|
/// A service descriptor.
|
||||||
|
|||||||
@@ -9,10 +9,15 @@ pub struct ServiceDef {
|
|||||||
name_str: String,
|
name_str: String,
|
||||||
package: String,
|
package: String,
|
||||||
proto_name: String,
|
proto_name: String,
|
||||||
|
proto_path: String,
|
||||||
methods: Vec<(Method, Ident)>,
|
methods: Vec<(Method, Ident)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_service_impl(item: ItemImpl, mut service: Service) -> ServiceDef {
|
pub(crate) fn parse_service_impl(
|
||||||
|
item: ItemImpl,
|
||||||
|
mut service: Service,
|
||||||
|
proto_path: String,
|
||||||
|
) -> ServiceDef {
|
||||||
let ItemImpl { self_ty, items, .. } = item;
|
let ItemImpl { self_ty, items, .. } = item;
|
||||||
|
|
||||||
let name = if let Type::Path(t) = *self_ty {
|
let name = if let Type::Path(t) = *self_ty {
|
||||||
@@ -48,6 +53,7 @@ pub(crate) fn parse_service_impl(item: ItemImpl, mut service: Service) -> Servic
|
|||||||
name_str: service.name,
|
name_str: service.name,
|
||||||
package: service.package,
|
package: service.package,
|
||||||
proto_name: service.proto_name,
|
proto_name: service.proto_name,
|
||||||
|
proto_path,
|
||||||
methods,
|
methods,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,7 +126,12 @@ fn generate_methods(service: &ServiceDef) -> TokenStream {
|
|||||||
);
|
);
|
||||||
let method_path = Lit::Str(LitStr::new(&path, Span::call_site()));
|
let method_path = Lit::Str(LitStr::new(&path, Span::call_site()));
|
||||||
|
|
||||||
let method_stream = generate_unary(method, ident.clone(), service.name.clone());
|
let method_stream = generate_unary(
|
||||||
|
method,
|
||||||
|
ident.clone(),
|
||||||
|
service.name.clone(),
|
||||||
|
&service.proto_path,
|
||||||
|
);
|
||||||
|
|
||||||
let method = quote! {
|
let method = quote! {
|
||||||
#method_path => {
|
#method_path => {
|
||||||
@@ -133,11 +144,17 @@ fn generate_methods(service: &ServiceDef) -> TokenStream {
|
|||||||
stream
|
stream
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_unary(method: &Method, method_ident: Ident, service_impl: Path) -> TokenStream {
|
fn generate_unary(
|
||||||
|
method: &Method,
|
||||||
|
method_ident: Ident,
|
||||||
|
service_impl: Path,
|
||||||
|
proto_path: &str,
|
||||||
|
) -> TokenStream {
|
||||||
let service_ident = Ident::new(&method.proto_name, Span::call_site());
|
let service_ident = Ident::new(&method.proto_name, Span::call_site());
|
||||||
|
|
||||||
let request: Path = syn::parse_str(&format!("hello_world::{}", method.input_type)).unwrap();
|
let request: Path = syn::parse_str(&format!("{}::{}", proto_path, method.input_type)).unwrap();
|
||||||
let response: Path = syn::parse_str(&format!("hello_world::{}", method.output_type)).unwrap();
|
let response: Path =
|
||||||
|
syn::parse_str(&format!("{}::{}", proto_path, method.output_type)).unwrap();
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
struct #service_ident(pub std::sync::Arc<#service_impl>);
|
||||||
|
|||||||
Reference in New Issue
Block a user