Skip to content

Commit 06946f7

Browse files
committed
prost-build: pass Config, ServiceGenerator by mut ref
Changing ServiceGenerator::{generate, finalize} to take `&mut self` is motivated by tower-rs/tower-grpc#21. The `ServiceGenerator` change necessitated changing Config::compile_protos to take `&mut self` as well. I don't expect the latter change to impact many people, since it's the more advanced API (as opposed to the standalone `compile_protos` function), and to be useful the API required a mutable config, anyway. It also provides flexibility in the future if we want to do something else requiring mutable access to the config. This is a breaking change.
1 parent 5b93d0c commit 06946f7

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

benchmarks/build.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ extern crate protobuf;
33

44
fn main() {
55
let benchmarks = protobuf::include().join("benchmarks");
6-
let prost_build = prost_build::Config::new();
7-
prost_build.compile_protos(&[benchmarks.join("benchmark_messages_proto2.proto")],
8-
&[benchmarks.clone()]).unwrap();
9-
prost_build.compile_protos(&[benchmarks.join("benchmark_messages_proto3.proto")],
10-
&[benchmarks]).unwrap();
6+
prost_build::compile_protos(&[benchmarks.join("benchmark_messages_proto2.proto")],
7+
&[benchmarks.clone()]).unwrap();
8+
prost_build::compile_protos(&[benchmarks.join("benchmark_messages_proto3.proto")],
9+
&[benchmarks]).unwrap();
1110

1211
println!("cargo:rustc-env=GOOGLE_MESSAGE1={}",
1312
protobuf::share().join("google_message1.dat").display());

prost-build/src/code_generator.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ enum Syntax {
4646
}
4747

4848
pub struct CodeGenerator<'a> {
49-
config: &'a Config,
49+
config: &'a mut Config,
5050
package: String,
5151
source_info: SourceCodeInfo,
5252
syntax: Syntax,
@@ -57,7 +57,7 @@ pub struct CodeGenerator<'a> {
5757
}
5858

5959
impl <'a> CodeGenerator<'a> {
60-
pub fn generate(config: &Config,
60+
pub fn generate(config: &mut Config,
6161
message_graph: &MessageGraph,
6262
file: FileDescriptorProto,
6363
buf: &mut String) {
@@ -104,14 +104,19 @@ impl <'a> CodeGenerator<'a> {
104104
}
105105
code_gen.path.pop();
106106

107-
if let Some(ref service_generator) = code_gen.config.service_generator {
107+
if code_gen.config.service_generator.is_some() {
108108
code_gen.path.push(6);
109109
for (idx, service) in file.service.into_iter().enumerate() {
110110
code_gen.path.push(idx as i32);
111-
service_generator.generate(code_gen.unpack_service(service), &mut code_gen.buf);
111+
code_gen.push_service(service);
112112
code_gen.path.pop();
113113
}
114-
service_generator.finalize(&mut code_gen.buf);
114+
115+
let buf = code_gen.buf;
116+
code_gen.config.service_generator.as_mut().map(|service_generator| {
117+
service_generator.finalize(buf);
118+
});
119+
115120
code_gen.path.pop();
116121
}
117122
}
@@ -226,21 +231,23 @@ impl <'a> CodeGenerator<'a> {
226231

227232
fn append_type_attributes(&mut self, msg_name: &str) {
228233
assert_eq!(b'.', msg_name.as_bytes()[0]);
229-
for &(ref matcher, ref attribute) in &self.config.type_attributes {
230-
if match_ident(matcher, msg_name, None) {
234+
// TODO: this clone is dirty, but expedious.
235+
for (matcher, attribute) in self.config.type_attributes.clone() {
236+
if match_ident(&matcher, msg_name, None) {
231237
self.push_indent();
232-
self.buf.push_str(attribute);
238+
self.buf.push_str(&attribute);
233239
self.buf.push('\n');
234240
}
235241
}
236242
}
237243

238244
fn append_field_attributes(&mut self, msg_name: &str, field_name: &str) {
239245
assert_eq!(b'.', msg_name.as_bytes()[0]);
240-
for &(ref matcher, ref attribute) in &self.config.field_attributes {
241-
if match_ident(matcher, msg_name, Some(field_name)) {
246+
// TODO: this clone is dirty, but expedious.
247+
for (matcher, attribute) in self.config.field_attributes.clone() {
248+
if match_ident(&matcher, msg_name, Some(field_name)) {
242249
self.push_indent();
243-
self.buf.push_str(attribute);
250+
self.buf.push_str(&attribute);
244251
self.buf.push('\n');
245252
}
246253
}
@@ -491,7 +498,7 @@ impl <'a> CodeGenerator<'a> {
491498
self.buf.push_str(",\n");
492499
}
493500

494-
fn unpack_service(&mut self, service: ServiceDescriptorProto) -> Service {
501+
fn push_service(&mut self, service: ServiceDescriptorProto) {
495502
let name = service.name().to_owned();
496503
debug!(" service: {:?}", name);
497504

@@ -531,14 +538,17 @@ impl <'a> CodeGenerator<'a> {
531538
.collect();
532539
self.path.pop();
533540

534-
Service {
541+
let service = Service {
535542
name: to_upper_camel(&name),
536543
proto_name: name,
537544
package: self.package.clone(),
538545
comments,
539546
methods,
540547
options: service.options.unwrap_or_default(),
541-
}
548+
};
549+
550+
let buf = &mut self.buf;
551+
self.config.service_generator.as_mut().map(move |service_generator| service_generator.generate(service, buf));
542552
}
543553

544554
fn push_indent(&mut self) {

prost-build/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ type Module = Vec<String>;
172172
pub trait ServiceGenerator {
173173
/// Generates a Rust interface or implementation for a service, writing the
174174
/// result to `buf`.
175-
fn generate(&self, service: Service, buf: &mut String);
175+
fn generate(&mut self, service: Service, buf: &mut String);
176176

177177
/// Finalizes the generation process.
178178
///
@@ -187,7 +187,7 @@ pub trait ServiceGenerator {
187187
/// is called once per `.proto` file.
188188
///
189189
/// The default implementation is empty and does nothing.
190-
fn finalize(&self, _buf: &mut String) {}
190+
fn finalize(&mut self, _buf: &mut String) {}
191191
}
192192

193193
/// Configuration options for Protobuf code generation.
@@ -371,7 +371,7 @@ impl Config {
371371
/// &["src"]).unwrap();
372372
/// }
373373
/// ```
374-
pub fn compile_protos<P>(&self, protos: &[P], includes: &[P]) -> Result<()> where P: AsRef<Path> {
374+
pub fn compile_protos<P>(&mut self, protos: &[P], includes: &[P]) -> Result<()> where P: AsRef<Path> {
375375
let target = match env::var("OUT_DIR") {
376376
Ok(val) => PathBuf::from(val),
377377
Err(env::VarError::NotPresent) => {
@@ -434,7 +434,7 @@ impl Config {
434434
Ok(())
435435
}
436436

437-
fn generate(&self, files: Vec<FileDescriptorProto>) -> HashMap<Module, String> {
437+
fn generate(&mut self, files: Vec<FileDescriptorProto>) -> HashMap<Module, String> {
438438
let mut modules = HashMap::new();
439439

440440
let message_graph = MessageGraph::new(&files);
@@ -525,7 +525,7 @@ mod tests {
525525
/// service methods.
526526
struct ServiceTraitGenerator;
527527
impl ServiceGenerator for ServiceTraitGenerator {
528-
fn generate(&self, service: Service, buf: &mut String) {
528+
fn generate(&mut self, service: Service, buf: &mut String) {
529529
// Generate a trait for the service.
530530
service.comments.append_with_indent(0, buf);
531531
buf.push_str(&format!("trait {} {{\n", &service.name));
@@ -542,7 +542,7 @@ mod tests {
542542
// Close out the trait.
543543
buf.push_str("}\n");
544544
}
545-
fn finalize(&self, buf: &mut String) {
545+
fn finalize(&mut self, buf: &mut String) {
546546
// Needs to be present only once, no matter how many services there are
547547
buf.push_str("pub mod utils { }\n");
548548
}

0 commit comments

Comments
 (0)