proto_build_kit/lib.rs
1// SPDX-License-Identifier: MIT
2//! Generic build-helper primitives for proto-source services.
3//!
4//! The four primitives this crate exposes are the ones every
5//! `.proto`-publishing or `.proto`-consuming Rust crate ends up
6//! reimplementing:
7//!
8//! 1. **Stage embedded proto bytes onto a tempdir** at protoc-relative
9//! paths so `import "myproto/v1/foo.proto";` resolves at build time
10//! without the consumer vendoring the file ([`Stager`]).
11//! 2. **Compile `.proto` files via `protox`** (pure Rust, no `protoc`
12//! subprocess) and return both the `prost-reflect` descriptor pool
13//! (preserves custom-option VALUES) and the FDS bytes for downstream
14//! codegen ([`compile_protos`]).
15//! 3. **Read `MethodOptions` extension values** from the descriptor pool
16//! — encoded FDS drops them, the pool keeps them
17//! ([`extract_method_string_extension`]).
18//! 4. **Drive `tonic-prost-build`** with `type_attribute(...)` injection
19//! from an annotation-FQN map ([`tonic_prost_build_with_attrs`], gated
20//! on the `tonic` feature).
21//!
22//! The crate is **schema-agnostic** — it doesn't know about any specific
23//! proto package or annotation. Consumers pair it with a tiny sibling
24//! crate that ships their `.proto` bytes via `include_bytes!`:
25//!
26//! ```ignore
27//! // some-protos/src/lib.rs (your bytes crate):
28//! const FOO: &[u8] = include_bytes!("../proto/my/v1/foo.proto");
29//! pub fn files() -> impl Iterator<Item = (&'static str, &'static [u8])> {
30//! [("my/v1/foo.proto", FOO)].into_iter()
31//! }
32//! ```
33//!
34//! Consumer `build.rs` then composes any number of `*-protos` crates:
35//!
36//! ```ignore
37//! use proto_build_kit::Stager;
38//!
39//! fn main() -> Result<(), Box<dyn std::error::Error>> {
40//! let staged = Stager::new()
41//! .with(some_protos::files())
42//! .with(other_protos::files())
43//! .stage()?;
44//!
45//! // Drive whatever codegen you want (connectrpc-build, tonic, ...)
46//! // against `staged.path()` on the include path.
47//! Ok(())
48//! }
49//! ```
50//!
51//! Hold the returned [`tempfile::TempDir`] until codegen completes —
52//! drop deletes the staged files.
53
54#![doc(html_root_url = "https://docs.rs/proto-build-kit/0.1.0")]
55
56mod compile;
57mod errors;
58mod extract;
59mod stage;
60
61#[cfg(feature = "tonic")]
62mod codegen_tonic;
63
64pub use compile::{CompileOutput, compile_protos};
65pub use errors::Error;
66pub use extract::extract_method_string_extension;
67pub use stage::Stager;
68
69#[cfg(feature = "tonic")]
70pub use codegen_tonic::tonic_prost_build_with_attrs;