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"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/hyperium/tonic"
|
||||
version = "0.8.2"
|
||||
version = "0.8.3"
|
||||
|
||||
[dependencies]
|
||||
prettyplease = { version = "0.1" }
|
||||
|
||||
@@ -9,6 +9,7 @@ use quote::{format_ident, quote};
|
||||
///
|
||||
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||
/// a public module with the generated client.
|
||||
#[deprecated(since = "0.8.3", note = "Use the CodeGenBuilder::generate_client")]
|
||||
pub fn generate<T: Service>(
|
||||
service: &T,
|
||||
emit_package: bool,
|
||||
@@ -16,6 +17,25 @@ pub fn generate<T: Service>(
|
||||
compile_well_known_types: bool,
|
||||
build_transport: bool,
|
||||
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>,
|
||||
) -> TokenStream {
|
||||
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
|
||||
pub mod server;
|
||||
|
||||
mod code_gen;
|
||||
pub use code_gen::CodeGen8uilder;
|
||||
|
||||
/// Service generation trait.
|
||||
///
|
||||
/// 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 quote::ToTokens;
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
@@ -352,27 +352,21 @@ struct ServiceGenerator {
|
||||
impl ServiceGenerator {
|
||||
fn generate(&mut self, service: &Service) {
|
||||
if self.builder.build_server {
|
||||
let server = server::generate(
|
||||
service,
|
||||
true, // emit_package,
|
||||
"", // proto_path, -- not used
|
||||
false, // compile_well_known_types -- not used
|
||||
&Attributes::default(),
|
||||
&HashSet::default(),
|
||||
);
|
||||
let server = CodeGen8uilder::new()
|
||||
.emit_package(true)
|
||||
.compile_well_known_types(false)
|
||||
.generate_server(service, "");
|
||||
|
||||
self.servers.extend(server);
|
||||
}
|
||||
|
||||
if self.builder.build_client {
|
||||
let client = client::generate(
|
||||
service,
|
||||
true, // emit_package,
|
||||
"", // proto_path, -- not used
|
||||
false, // compile_well_known_types, -- not used
|
||||
self.builder.build_transport,
|
||||
&Attributes::default(),
|
||||
&HashSet::default(),
|
||||
);
|
||||
let client = CodeGen8uilder::new()
|
||||
.emit_package(true)
|
||||
.compile_well_known_types(false)
|
||||
.build_transport(self.builder.build_transport)
|
||||
.generate_client(service, "");
|
||||
|
||||
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 prost_build::{Config, Method, Service};
|
||||
use quote::ToTokens;
|
||||
@@ -159,27 +161,25 @@ impl ServiceGenerator {
|
||||
impl prost_build::ServiceGenerator for ServiceGenerator {
|
||||
fn generate(&mut self, service: prost_build::Service, _buf: &mut String) {
|
||||
if self.builder.build_server {
|
||||
let server = server::generate(
|
||||
&service,
|
||||
self.builder.emit_package,
|
||||
&self.builder.proto_path,
|
||||
self.builder.compile_well_known_types,
|
||||
&self.builder.server_attributes,
|
||||
&self.builder.disable_comments,
|
||||
);
|
||||
let server = CodeGen8uilder::new()
|
||||
.emit_package(self.builder.emit_package)
|
||||
.compile_well_known_types(self.builder.compile_well_known_types)
|
||||
.attributes(self.builder.server_attributes.clone())
|
||||
.disable_comments(self.builder.disable_comments.clone())
|
||||
.generate_server(&service, &self.builder.proto_path);
|
||||
|
||||
self.servers.extend(server);
|
||||
}
|
||||
|
||||
if self.builder.build_client {
|
||||
let client = client::generate(
|
||||
&service,
|
||||
self.builder.emit_package,
|
||||
&self.builder.proto_path,
|
||||
self.builder.compile_well_known_types,
|
||||
self.builder.build_transport,
|
||||
&self.builder.client_attributes,
|
||||
&self.builder.disable_comments,
|
||||
);
|
||||
let client = CodeGen8uilder::new()
|
||||
.emit_package(self.builder.emit_package)
|
||||
.compile_well_known_types(self.builder.compile_well_known_types)
|
||||
.attributes(self.builder.client_attributes.clone())
|
||||
.disable_comments(self.builder.disable_comments.clone())
|
||||
.build_transport(self.builder.build_transport)
|
||||
.generate_client(&service, &self.builder.proto_path);
|
||||
|
||||
self.clients.extend(client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,12 +10,30 @@ use syn::{Ident, Lit, LitStr};
|
||||
///
|
||||
/// This takes some `Service` and will generate a `TokenStream` that contains
|
||||
/// 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>(
|
||||
service: &T,
|
||||
emit_package: bool,
|
||||
proto_path: &str,
|
||||
compile_well_known_types: bool,
|
||||
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>,
|
||||
) -> TokenStream {
|
||||
let methods = generate_methods(service, proto_path, compile_well_known_types);
|
||||
|
||||
Reference in New Issue
Block a user