use std::path::Path;
use prost::Message as _;
use crate::Error;
pub struct CompileOutput {
pub pool: prost_reflect::DescriptorPool,
pub fds_bytes: Vec<u8>,
}
pub fn compile_protos<P: AsRef<Path>, Q: AsRef<Path>>(
protos: &[P],
includes: &[Q],
) -> Result<CompileOutput, Error> {
let mut compiler = protox::Compiler::new(includes.iter().map(AsRef::as_ref))?;
compiler.include_imports(true);
compiler.include_source_info(false);
for p in protos {
compiler.open_file(p.as_ref())?;
}
let pool = compiler.descriptor_pool();
let fds_bytes = compiler.file_descriptor_set().encode_to_vec();
Ok(CompileOutput { pool, fds_bytes })
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Stager;
#[test]
fn compiles_trivial_proto() {
let staged = Stager::new()
.add(
"fixture/v1/x.proto",
b"syntax = \"proto3\"; package fixture.v1; message Foo { string id = 1; }",
)
.stage()
.unwrap();
let out = compile_protos(&["fixture/v1/x.proto"], &[staged.path()]).expect("compile");
assert!(!out.fds_bytes.is_empty());
let foo = out
.pool
.get_message_by_name("fixture.v1.Foo")
.expect("Foo in pool");
assert_eq!(foo.fields().count(), 1);
}
}