feat(build): Add CodeGenBuilder (#1154)
This commit adds a new `CodeGenBuilder` that replaces the client/server generate fn with a builder stlye that allows adding config items in an non-breaking way. This also deprecates both of the client/server generate fn in favor of the builder ones.
This commit is contained in:
@@ -12,7 +12,7 @@ license = "MIT"
|
|||||||
name = "tonic-build"
|
name = "tonic-build"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/hyperium/tonic"
|
repository = "https://github.com/hyperium/tonic"
|
||||||
version = "0.8.2"
|
version = "0.8.3"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
prettyplease = { version = "0.1" }
|
prettyplease = { version = "0.1" }
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use quote::{format_ident, quote};
|
|||||||
///
|
///
|
||||||
/// This takes some `Service` and will generate a `TokenStream` that contains
|
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||||
/// a public module with the generated client.
|
/// a public module with the generated client.
|
||||||
|
#[deprecated(since = "0.8.3", note = "Use the CodeGenBuilder::generate_client")]
|
||||||
pub fn generate<T: Service>(
|
pub fn generate<T: Service>(
|
||||||
service: &T,
|
service: &T,
|
||||||
emit_package: bool,
|
emit_package: bool,
|
||||||
@@ -16,6 +17,25 @@ pub fn generate<T: Service>(
|
|||||||
compile_well_known_types: bool,
|
compile_well_known_types: bool,
|
||||||
build_transport: bool,
|
build_transport: bool,
|
||||||
attributes: &Attributes,
|
attributes: &Attributes,
|
||||||
|
) -> TokenStream {
|
||||||
|
generate_internal(
|
||||||
|
service,
|
||||||
|
emit_package,
|
||||||
|
proto_path,
|
||||||
|
compile_well_known_types,
|
||||||
|
build_transport,
|
||||||
|
attributes,
|
||||||
|
&HashSet::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn generate_internal<T: Service>(
|
||||||
|
service: &T,
|
||||||
|
emit_package: bool,
|
||||||
|
proto_path: &str,
|
||||||
|
compile_well_known_types: bool,
|
||||||
|
build_transport: bool,
|
||||||
|
attributes: &Attributes,
|
||||||
disable_comments: &HashSet<String>,
|
disable_comments: &HashSet<String>,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let service_ident = quote::format_ident!("{}Client", service.name());
|
let service_ident = quote::format_ident!("{}Client", service.name());
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
|
||||||
|
use crate::{Attributes, Service};
|
||||||
|
|
||||||
|
/// Builder for the generic code generation of server and clients.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CodeGen8uilder {
|
||||||
|
emit_package: bool,
|
||||||
|
compile_well_known_types: bool,
|
||||||
|
attributes: Attributes,
|
||||||
|
build_transport: bool,
|
||||||
|
disable_comments: HashSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodeGen8uilder {
|
||||||
|
/// Create a new code gen builder with default options.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable code generation to emit the package name.
|
||||||
|
pub fn emit_package(&mut self, enable: bool) -> &mut Self {
|
||||||
|
self.emit_package = enable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Attributes that will be added to `mod` and `struct` items.
|
||||||
|
///
|
||||||
|
/// Reference [`Attributes`] for more information.
|
||||||
|
pub fn attributes(&mut self, attributes: Attributes) -> &mut Self {
|
||||||
|
self.attributes = attributes;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable transport code to be generated, this requires `tonic`'s `transport`
|
||||||
|
/// feature.
|
||||||
|
///
|
||||||
|
/// This allows codegen level control of generating the transport code and
|
||||||
|
/// is a work around when other crates in a workspace enable this feature.
|
||||||
|
pub fn build_transport(&mut self, build_transport: bool) -> &mut Self {
|
||||||
|
self.build_transport = build_transport;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enable compiling well knonw types, this will force codegen to not
|
||||||
|
/// use the well known types from `prost-types`.
|
||||||
|
pub fn compile_well_known_types(&mut self, enable: bool) -> &mut Self {
|
||||||
|
self.compile_well_known_types = enable;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disable comments based on a proto path.
|
||||||
|
pub fn disable_comments(&mut self, disable_comments: HashSet<String>) -> &mut Self {
|
||||||
|
self.disable_comments = disable_comments;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate client code based on `Service`.
|
||||||
|
///
|
||||||
|
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||||
|
/// a public module with the generated client.
|
||||||
|
pub fn generate_client(&self, service: &impl Service, proto_path: &str) -> TokenStream {
|
||||||
|
crate::client::generate_internal(
|
||||||
|
service,
|
||||||
|
self.emit_package,
|
||||||
|
proto_path,
|
||||||
|
self.compile_well_known_types,
|
||||||
|
self.build_transport,
|
||||||
|
&self.attributes,
|
||||||
|
&self.disable_comments,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate server code based on `Service`.
|
||||||
|
///
|
||||||
|
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||||
|
/// a public module with the generated client.
|
||||||
|
pub fn generate_server(&self, service: &impl Service, proto_path: &str) -> TokenStream {
|
||||||
|
crate::server::generate_internal(
|
||||||
|
service,
|
||||||
|
self.emit_package,
|
||||||
|
proto_path,
|
||||||
|
self.compile_well_known_types,
|
||||||
|
&self.attributes,
|
||||||
|
&self.disable_comments,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CodeGen8uilder {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
emit_package: true,
|
||||||
|
compile_well_known_types: false,
|
||||||
|
attributes: Attributes::default(),
|
||||||
|
build_transport: true,
|
||||||
|
disable_comments: HashSet::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,6 +94,9 @@ pub mod client;
|
|||||||
/// Service code generation for Server
|
/// Service code generation for Server
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|
||||||
|
mod code_gen;
|
||||||
|
pub use code_gen::CodeGen8uilder;
|
||||||
|
|
||||||
/// Service generation trait.
|
/// Service generation trait.
|
||||||
///
|
///
|
||||||
/// This trait can be implemented and consumed
|
/// This trait can be implemented and consumed
|
||||||
|
|||||||
+13
-19
@@ -28,11 +28,11 @@
|
|||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use super::{client, server, Attributes};
|
use crate::code_gen::CodeGen8uilder;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
|
||||||
fs,
|
fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
@@ -352,27 +352,21 @@ struct ServiceGenerator {
|
|||||||
impl ServiceGenerator {
|
impl ServiceGenerator {
|
||||||
fn generate(&mut self, service: &Service) {
|
fn generate(&mut self, service: &Service) {
|
||||||
if self.builder.build_server {
|
if self.builder.build_server {
|
||||||
let server = server::generate(
|
let server = CodeGen8uilder::new()
|
||||||
service,
|
.emit_package(true)
|
||||||
true, // emit_package,
|
.compile_well_known_types(false)
|
||||||
"", // proto_path, -- not used
|
.generate_server(service, "");
|
||||||
false, // compile_well_known_types -- not used
|
|
||||||
&Attributes::default(),
|
|
||||||
&HashSet::default(),
|
|
||||||
);
|
|
||||||
self.servers.extend(server);
|
self.servers.extend(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.builder.build_client {
|
if self.builder.build_client {
|
||||||
let client = client::generate(
|
let client = CodeGen8uilder::new()
|
||||||
service,
|
.emit_package(true)
|
||||||
true, // emit_package,
|
.compile_well_known_types(false)
|
||||||
"", // proto_path, -- not used
|
.build_transport(self.builder.build_transport)
|
||||||
false, // compile_well_known_types, -- not used
|
.generate_client(service, "");
|
||||||
self.builder.build_transport,
|
|
||||||
&Attributes::default(),
|
|
||||||
&HashSet::default(),
|
|
||||||
);
|
|
||||||
self.clients.extend(client);
|
self.clients.extend(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-18
@@ -1,4 +1,6 @@
|
|||||||
use super::{client, server, Attributes};
|
use crate::code_gen::CodeGen8uilder;
|
||||||
|
|
||||||
|
use super::Attributes;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use prost_build::{Config, Method, Service};
|
use prost_build::{Config, Method, Service};
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
@@ -159,27 +161,25 @@ impl ServiceGenerator {
|
|||||||
impl prost_build::ServiceGenerator for ServiceGenerator {
|
impl prost_build::ServiceGenerator for ServiceGenerator {
|
||||||
fn generate(&mut self, service: prost_build::Service, _buf: &mut String) {
|
fn generate(&mut self, service: prost_build::Service, _buf: &mut String) {
|
||||||
if self.builder.build_server {
|
if self.builder.build_server {
|
||||||
let server = server::generate(
|
let server = CodeGen8uilder::new()
|
||||||
&service,
|
.emit_package(self.builder.emit_package)
|
||||||
self.builder.emit_package,
|
.compile_well_known_types(self.builder.compile_well_known_types)
|
||||||
&self.builder.proto_path,
|
.attributes(self.builder.server_attributes.clone())
|
||||||
self.builder.compile_well_known_types,
|
.disable_comments(self.builder.disable_comments.clone())
|
||||||
&self.builder.server_attributes,
|
.generate_server(&service, &self.builder.proto_path);
|
||||||
&self.builder.disable_comments,
|
|
||||||
);
|
|
||||||
self.servers.extend(server);
|
self.servers.extend(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.builder.build_client {
|
if self.builder.build_client {
|
||||||
let client = client::generate(
|
let client = CodeGen8uilder::new()
|
||||||
&service,
|
.emit_package(self.builder.emit_package)
|
||||||
self.builder.emit_package,
|
.compile_well_known_types(self.builder.compile_well_known_types)
|
||||||
&self.builder.proto_path,
|
.attributes(self.builder.client_attributes.clone())
|
||||||
self.builder.compile_well_known_types,
|
.disable_comments(self.builder.disable_comments.clone())
|
||||||
self.builder.build_transport,
|
.build_transport(self.builder.build_transport)
|
||||||
&self.builder.client_attributes,
|
.generate_client(&service, &self.builder.proto_path);
|
||||||
&self.builder.disable_comments,
|
|
||||||
);
|
|
||||||
self.clients.extend(client);
|
self.clients.extend(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,30 @@ use syn::{Ident, Lit, LitStr};
|
|||||||
///
|
///
|
||||||
/// This takes some `Service` and will generate a `TokenStream` that contains
|
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||||
/// a public module containing the server service and handler trait.
|
/// a public module containing the server service and handler trait.
|
||||||
|
#[deprecated(since = "0.8.3", note = "Use CodeGenBuilder::generate_server")]
|
||||||
pub fn generate<T: Service>(
|
pub fn generate<T: Service>(
|
||||||
service: &T,
|
service: &T,
|
||||||
emit_package: bool,
|
emit_package: bool,
|
||||||
proto_path: &str,
|
proto_path: &str,
|
||||||
compile_well_known_types: bool,
|
compile_well_known_types: bool,
|
||||||
attributes: &Attributes,
|
attributes: &Attributes,
|
||||||
|
) -> TokenStream {
|
||||||
|
generate_internal(
|
||||||
|
service,
|
||||||
|
emit_package,
|
||||||
|
proto_path,
|
||||||
|
compile_well_known_types,
|
||||||
|
attributes,
|
||||||
|
&HashSet::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn generate_internal<T: Service>(
|
||||||
|
service: &T,
|
||||||
|
emit_package: bool,
|
||||||
|
proto_path: &str,
|
||||||
|
compile_well_known_types: bool,
|
||||||
|
attributes: &Attributes,
|
||||||
disable_comments: &HashSet<String>,
|
disable_comments: &HashSet<String>,
|
||||||
) -> TokenStream {
|
) -> TokenStream {
|
||||||
let methods = generate_methods(service, proto_path, compile_well_known_types);
|
let methods = generate_methods(service, proto_path, compile_well_known_types);
|
||||||
|
|||||||
Reference in New Issue
Block a user