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.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
tags
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ mod server;
|
|||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
build_client: bool,
|
build_client: bool,
|
||||||
build_server: bool,
|
build_server: bool,
|
||||||
|
field_attributes: Vec<(String, String)>,
|
||||||
|
type_attributes: Vec<(String, String)>,
|
||||||
out_dir: Option<PathBuf>,
|
out_dir: Option<PathBuf>,
|
||||||
#[cfg(feature = "rustfmt")]
|
#[cfg(feature = "rustfmt")]
|
||||||
format: bool,
|
format: bool,
|
||||||
@@ -109,6 +111,24 @@ impl Builder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add additional attribute to matched messages, enums, and one-offs.
|
||||||
|
///
|
||||||
|
/// Passed directly to `prost_build::Config.field_attribute`.
|
||||||
|
pub fn field_attribute<P: AsRef<str>, A: AsRef<str>>(mut self, path: P, attribute: A) -> Self {
|
||||||
|
self.field_attributes
|
||||||
|
.push((path.as_ref().to_string(), attribute.as_ref().to_string()));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add additional attribute to matched messages, enums, and one-offs.
|
||||||
|
///
|
||||||
|
/// Passed directly to `prost_build::Config.type_attribute`.
|
||||||
|
pub fn type_attribute<P: AsRef<str>, A: AsRef<str>>(mut self, path: P, attribute: A) -> Self {
|
||||||
|
self.type_attributes
|
||||||
|
.push((path.as_ref().to_string(), attribute.as_ref().to_string()));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Compile the .proto files and execute code generation.
|
/// Compile the .proto files and execute code generation.
|
||||||
pub fn compile<P: AsRef<Path>>(self, protos: &[P], includes: &[P]) -> io::Result<()> {
|
pub fn compile<P: AsRef<Path>>(self, protos: &[P], includes: &[P]) -> io::Result<()> {
|
||||||
let mut config = Config::new();
|
let mut config = Config::new();
|
||||||
@@ -122,7 +142,14 @@ impl Builder {
|
|||||||
.unwrap_or_else(|| PathBuf::from(std::env::var("OUT_DIR").unwrap()));
|
.unwrap_or_else(|| PathBuf::from(std::env::var("OUT_DIR").unwrap()));
|
||||||
|
|
||||||
config.out_dir(out_dir.clone());
|
config.out_dir(out_dir.clone());
|
||||||
|
for (path, attr) in self.field_attributes.iter() {
|
||||||
|
config.field_attribute(path, attr);
|
||||||
|
}
|
||||||
|
for (path, attr) in self.type_attributes.iter() {
|
||||||
|
config.type_attribute(path, attr);
|
||||||
|
}
|
||||||
config.service_generator(Box::new(ServiceGenerator::new(self)));
|
config.service_generator(Box::new(ServiceGenerator::new(self)));
|
||||||
|
|
||||||
config.compile_protos(protos, includes)?;
|
config.compile_protos(protos, includes)?;
|
||||||
|
|
||||||
#[cfg(feature = "rustfmt")]
|
#[cfg(feature = "rustfmt")]
|
||||||
@@ -144,6 +171,8 @@ pub fn configure() -> Builder {
|
|||||||
build_client: true,
|
build_client: true,
|
||||||
build_server: true,
|
build_server: true,
|
||||||
out_dir: None,
|
out_dir: None,
|
||||||
|
field_attributes: Vec::new(),
|
||||||
|
type_attributes: Vec::new(),
|
||||||
#[cfg(feature = "rustfmt")]
|
#[cfg(feature = "rustfmt")]
|
||||||
format: true,
|
format: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ fn wellknown() {
|
|||||||
tonic_build::configure()
|
tonic_build::configure()
|
||||||
.out_dir(tmp)
|
.out_dir(tmp)
|
||||||
.format(false)
|
.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"])
|
.compile(&["tests/protos/wellknown.proto"], &["tests/protos"])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user