Skip to content

Commit 06ff619

Browse files
adamhjkLucioFranco
authored andcommitted
feat(build): Expose prost-build type_attributes and field_attribu… (#60)
* chore: Add tags to .gitignore When generating ctags/universal-ctags, a 'tags' file is generated. This commit adds any generted 'tags' file to .gitignore. * feat(build): Expose type_attribute and field_attribute This commit exposes the `type_attribute` and `field_attribute` configuration settings from Prost. These are useful to tweak/extend the generated types. For example: ``` tonic_build::configure() .out_dir(tmp) .format(false) .type_attribute(".", "#[derive(Serialize, Deserialize)]") .type_attribute(".", "#[serde(rename_all = \"camelCase\")]") .field_attribute("in", "#[serde(rename = \"in\")]") .compile(&["tests/protos/wellknown.proto"], &["tests/protos"]) .unwrap(); ``` Would add the serde `Serialize` and `Deserialize` traits, while renaming all the fields to camelCase, and having serde keep fields named `in` named `in`, rather than Prost's `in_`, to every type generated by Prost.
1 parent 8db3961 commit 06ff619

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
**/*.rs.bk
33
Cargo.lock
4+
tags

tonic-build/src/lib.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ mod server;
7676
pub struct Builder {
7777
build_client: bool,
7878
build_server: bool,
79+
field_attributes: Vec<(String, String)>,
80+
type_attributes: Vec<(String, String)>,
7981
out_dir: Option<PathBuf>,
8082
#[cfg(feature = "rustfmt")]
8183
format: bool,
@@ -109,6 +111,24 @@ impl Builder {
109111
self
110112
}
111113

114+
/// Add additional attribute to matched messages, enums, and one-offs.
115+
///
116+
/// Passed directly to `prost_build::Config.field_attribute`.
117+
pub fn field_attribute<P: AsRef<str>, A: AsRef<str>>(mut self, path: P, attribute: A) -> Self {
118+
self.field_attributes
119+
.push((path.as_ref().to_string(), attribute.as_ref().to_string()));
120+
self
121+
}
122+
123+
/// Add additional attribute to matched messages, enums, and one-offs.
124+
///
125+
/// Passed directly to `prost_build::Config.type_attribute`.
126+
pub fn type_attribute<P: AsRef<str>, A: AsRef<str>>(mut self, path: P, attribute: A) -> Self {
127+
self.type_attributes
128+
.push((path.as_ref().to_string(), attribute.as_ref().to_string()));
129+
self
130+
}
131+
112132
/// Compile the .proto files and execute code generation.
113133
pub fn compile<P: AsRef<Path>>(self, protos: &[P], includes: &[P]) -> io::Result<()> {
114134
let mut config = Config::new();
@@ -122,7 +142,14 @@ impl Builder {
122142
.unwrap_or_else(|| PathBuf::from(std::env::var("OUT_DIR").unwrap()));
123143

124144
config.out_dir(out_dir.clone());
145+
for (path, attr) in self.field_attributes.iter() {
146+
config.field_attribute(path, attr);
147+
}
148+
for (path, attr) in self.type_attributes.iter() {
149+
config.type_attribute(path, attr);
150+
}
125151
config.service_generator(Box::new(ServiceGenerator::new(self)));
152+
126153
config.compile_protos(protos, includes)?;
127154

128155
#[cfg(feature = "rustfmt")]
@@ -144,6 +171,8 @@ pub fn configure() -> Builder {
144171
build_client: true,
145172
build_server: true,
146173
out_dir: None,
174+
field_attributes: Vec::new(),
175+
type_attributes: Vec::new(),
147176
#[cfg(feature = "rustfmt")]
148177
format: true,
149178
}

tonic-build/tests/wellknown.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ fn wellknown() {
44
tonic_build::configure()
55
.out_dir(tmp)
66
.format(false)
7+
.type_attribute(".", "#[derive(Serialize, Deserialize)]")
8+
.type_attribute(".", "#[serde(rename_all = \"camelCase\")]")
9+
.field_attribute("in", "#[serde(rename = \"in\")]")
710
.compile(&["tests/protos/wellknown.proto"], &["tests/protos"])
811
.unwrap();
912
}

0 commit comments

Comments
 (0)