Add service generator extensability
This commit is contained in:
parent
3f2fde50c9
commit
79c95a0018
4 changed files with 92 additions and 13 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -287,6 +287,7 @@ dependencies = [
|
||||||
"prettyplease 0.2.4",
|
"prettyplease 0.2.4",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"prost-build",
|
"prost-build",
|
||||||
|
"prost-types",
|
||||||
"protox",
|
"protox",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.13",
|
"syn 2.0.13",
|
||||||
|
|
|
@ -13,6 +13,7 @@ description = "Yet another remote procedure call library - codegen"
|
||||||
# gRPC/protobuf
|
# gRPC/protobuf
|
||||||
protox = "0.3"
|
protox = "0.3"
|
||||||
prost-build = "0.11"
|
prost-build = "0.11"
|
||||||
|
prost-types = "0.11"
|
||||||
|
|
||||||
# code gen
|
# code gen
|
||||||
prettyplease = "0.2"
|
prettyplease = "0.2"
|
||||||
|
|
|
@ -3,37 +3,114 @@ use std::convert::AsRef;
|
||||||
use std::iter::IntoIterator;
|
use std::iter::IntoIterator;
|
||||||
|
|
||||||
use prost_build::Config;
|
use prost_build::Config;
|
||||||
|
use prost_build::{Service, ServiceGenerator};
|
||||||
|
use prost_types::FileDescriptorSet;
|
||||||
|
|
||||||
|
/// Proto -> Rust transpiler configurator
|
||||||
|
pub struct Transpiler {
|
||||||
|
prost_config: Config,
|
||||||
|
files: FileDescriptorSet,
|
||||||
|
service_generator: MergedServiceGenerator,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Transpiler {
|
||||||
|
pub fn new(
|
||||||
|
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
|
includes: impl IntoIterator<Item = impl AsRef<Path>>
|
||||||
|
) -> Result<Self, impl std::error::Error> {
|
||||||
|
Ok::<_, protox::Error>(Self {
|
||||||
|
prost_config: Config::new(),
|
||||||
|
files: protox::compile(files, includes)?,
|
||||||
|
service_generator: MergedServiceGenerator::empty()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate client and server service implementations
|
||||||
|
pub fn generate_all(mut self) -> Self {
|
||||||
|
self.service_generator.add_service(super::ProtobufServiceGenerator::all());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate server services implementations
|
||||||
|
pub fn generate_server(mut self) -> Self {
|
||||||
|
self.service_generator.add_service(super::ProtobufServiceGenerator::server());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generate client services implementations
|
||||||
|
pub fn generate_client(mut self) -> Self {
|
||||||
|
self.service_generator.add_service(super::ProtobufServiceGenerator::client());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add additional custom service generator
|
||||||
|
pub fn with_service_generator<S: ServiceGenerator + 'static>(mut self, gen: S) -> Self {
|
||||||
|
self.service_generator.add_service(gen);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Actually generate code
|
||||||
|
pub fn transpile(mut self) -> std::io::Result<()> {
|
||||||
|
self.prost_config
|
||||||
|
.service_generator(Box::new(self.service_generator))
|
||||||
|
.compile_fds(self.files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MergedServiceGenerator {
|
||||||
|
generators: Vec<Box<dyn ServiceGenerator + 'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MergedServiceGenerator {
|
||||||
|
fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
generators: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_service<S: ServiceGenerator + 'static>(&mut self, service: S) -> &mut Self {
|
||||||
|
self.generators.push(Box::new(service));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServiceGenerator for MergedServiceGenerator {
|
||||||
|
fn generate(&mut self, service: Service, buf: &mut String) {
|
||||||
|
for gen in &mut self.generators {
|
||||||
|
gen.generate(service.clone(), buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Compile proto files into Rust with server and client implementations
|
/// Compile proto files into Rust with server and client implementations
|
||||||
pub fn compile(
|
pub fn compile(
|
||||||
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
includes: impl IntoIterator<Item = impl AsRef<Path>>
|
includes: impl IntoIterator<Item = impl AsRef<Path>>
|
||||||
) {
|
) {
|
||||||
let file_descriptors = protox::compile(files, includes).unwrap();
|
Transpiler::new(files, includes).unwrap()
|
||||||
Config::new()
|
.generate_all()
|
||||||
.service_generator(Box::new(super::ProtobufServiceGenerator::all()))
|
.transpile()
|
||||||
.compile_fds(file_descriptors)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile proto files into Rust with only client implementations
|
||||||
pub fn compile_clients(
|
pub fn compile_clients(
|
||||||
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
includes: impl IntoIterator<Item = impl AsRef<Path>>,
|
includes: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
) {
|
) {
|
||||||
let file_descriptors = protox::compile(files, includes).unwrap();
|
Transpiler::new(files, includes).unwrap()
|
||||||
Config::new()
|
.generate_client()
|
||||||
.service_generator(Box::new(super::ProtobufServiceGenerator::client()))
|
.transpile()
|
||||||
.compile_fds(file_descriptors)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compile proto files into Rust with only server implementations
|
||||||
pub fn compile_servers(
|
pub fn compile_servers(
|
||||||
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
files: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
includes: impl IntoIterator<Item = impl AsRef<Path>>,
|
includes: impl IntoIterator<Item = impl AsRef<Path>>,
|
||||||
) {
|
) {
|
||||||
let file_descriptors = protox::compile(files, includes).unwrap();
|
Transpiler::new(files, includes).unwrap()
|
||||||
Config::new()
|
.generate_server()
|
||||||
.service_generator(Box::new(super::ProtobufServiceGenerator::server()))
|
.transpile()
|
||||||
.compile_fds(file_descriptors)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
mod builder;
|
mod builder;
|
||||||
mod service_gen;
|
mod service_gen;
|
||||||
|
|
||||||
pub use builder::{compile, compile_servers, compile_clients};
|
pub use builder::{compile, compile_servers, compile_clients, Transpiler};
|
||||||
pub(crate) use service_gen::ProtobufServiceGenerator;
|
pub(crate) use service_gen::ProtobufServiceGenerator;
|
||||||
|
|
Loading…
Reference in a new issue