Skip to main content

tonin_build/
lib.rs

1//! `build.rs` helper that wraps [`tonic-build`] with tonin conventions.
2//!
3//! Call [`compile`] from a service crate's `build.rs` with the protos to
4//! compile and the include paths to resolve `import` statements against.
5//! Both gRPC client and server stubs are generated; the output lands in
6//! `OUT_DIR` and is pulled in with `tonic::include_proto!("<package>")`.
7//!
8//! # Example
9//!
10//! ```no_run
11//! fn main() -> Result<(), Box<dyn std::error::Error>> {
12//!     // Skip codegen if protoc is unavailable so the workspace still
13//!     // `cargo check`s without system protoc installed.
14//!     // Set TONIN_SKIP_PROTOC=1 to skip.
15//!     if std::env::var("TONIN_SKIP_PROTOC").is_ok() {
16//!         return Ok(());
17//!     }
18//!     tonin_build::compile(&["proto/greeter.proto"], &["proto"])
19//! }
20//! ```
21//!
22//! # Cargo.toml
23//!
24//! ```toml
25//! [build-dependencies]
26//! tonin-build = "0.1"
27//! ```
28//!
29//! Today every call to [`compile`] routes through `tonic-build` (prost).
30//! `TONIN_CODEC=buffa` is reserved for a future `protoc-gen-micro` codegen
31//! plugin; setting it today logs a notice to stderr and falls back to
32//! prost so scaffolds keep working unchanged. `TONIN_CODEC=prost` (or
33//! unset) is the explicit / default path.
34//!
35//! # Sample app
36//!
37//! <https://github.com/Rushit/tonin/tree/main/examples/greeter/blob/main/build.rs>
38//!
39//! # Sibling crates
40//!
41//! <https://docs.rs/tonin>
42//!
43//! [`tonic-build`]: https://crates.io/crates/tonic-build
44
45pub enum Codec {
46    Buffa,
47    Prost,
48}
49
50impl Codec {
51    fn from_env() -> Self {
52        match std::env::var("TONIN_CODEC").as_deref() {
53            Ok("prost") => Codec::Prost,
54            _ => Codec::Buffa, // default
55        }
56    }
57}
58
59pub fn compile(protos: &[&str], includes: &[&str]) -> Result<(), Box<dyn std::error::Error>> {
60    match Codec::from_env() {
61        Codec::Buffa => {
62            // TODO: invoke `protoc --plugin=protoc-gen-micro ...` once
63            // the codegen plugin is published. Falling back to tonic-build
64            // for now so the scaffold compiles end-to-end.
65            eprintln!(
66                "tonin-build: codec=buffa requested; falling back to prost (codegen plugin not yet wired)"
67            );
68            tonic_build::configure().compile_protos(protos, includes)?;
69        }
70        Codec::Prost => {
71            tonic_build::configure().compile_protos(protos, includes)?;
72        }
73    }
74    Ok(())
75}