diff --git a/Cargo.toml b/Cargo.toml index b13ec79..e5a0cd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,5 @@ members = [ "pbjson-build", "pbjson-test", "pbjson-types", + "pbjson-types/generator", ] diff --git a/pbjson-types/Cargo.toml b/pbjson-types/Cargo.toml index 60ce042..acb5944 100644 --- a/pbjson-types/Cargo.toml +++ b/pbjson-types/Cargo.toml @@ -18,7 +18,3 @@ serde = { version = "1.0", features = ["derive"] } [dev-dependencies] serde_json = "1.0" - -[build-dependencies] # In alphabetical order -prost-build = "0.11" -pbjson-build = { path = "../pbjson-build", version = "0.5" } diff --git a/pbjson-types/generator/Cargo.toml b/pbjson-types/generator/Cargo.toml new file mode 100644 index 0000000..081ab00 --- /dev/null +++ b/pbjson-types/generator/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "generator" +version = "0.1.0" +edition = "2021" +license = "MIT" +publish = false + +[dependencies] +clap = { version = "3", features = ["derive"] } +prost-build = "0.11" +pbjson-build = { path = "../../pbjson-build", version = "0.5" } +tempfile = "3.3.0" diff --git a/pbjson-types/build.rs b/pbjson-types/generator/src/main.rs similarity index 58% rename from pbjson-types/build.rs rename to pbjson-types/generator/src/main.rs index 8af9aeb..f8471cb 100644 --- a/pbjson-types/build.rs +++ b/pbjson-types/generator/src/main.rs @@ -1,28 +1,46 @@ //! Compiles Protocol Buffers and FlatBuffers schema definitions into //! native Rust types. +//! +//! This is kept as a separate binary to generate code for manual check-in, instead of running at +//! compile time as `build.rs` -- that way downstream consumers do not require the build +//! dependencies (espeically protoc) and can import rust sources directly. use std::env; use std::path::PathBuf; +use clap::Parser; + type Error = Box; type Result = std::result::Result; +#[derive(Parser)] +struct Args { + /// The path of the directory containing the protobuf sources. + #[clap(short, long, default_value = concat!(env!("CARGO_MANIFEST_DIR"), "/../protos"))] + input_proto_dir: PathBuf, + + /// The destination directory for generated code. + #[clap(short, long, default_value = concat!(env!("CARGO_MANIFEST_DIR"), "/../src/pb/"))] + output_dir: PathBuf, +} + fn main() -> Result<()> { - let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("protos"); + let args = Args::parse(); + let root = args.input_proto_dir; + let out_dir = &args.output_dir; let proto_files = vec![root.join("google/protobuf/types.proto")]; - // Tell cargo to recompile if any of these proto files are changed - for proto_file in &proto_files { - println!("cargo:rerun-if-changed={}", proto_file.display()); - } + std::fs::create_dir_all(out_dir)?; - let descriptor_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("proto_descriptor.bin"); + let temp_dir = tempfile::tempdir()?; + let descriptor_path = temp_dir.path().join("proto_descriptor.bin"); prost_build::Config::new() .file_descriptor_set_path(&descriptor_path) .compile_well_known_types() .disable_comments(&["."]) .bytes(&[".google"]) + .out_dir(out_dir) .compile_protos(&proto_files, &[root])?; let descriptor_set = std::fs::read(descriptor_path)?; @@ -45,6 +63,7 @@ fn main() -> Result<()> { ".google.protobuf.UInt32Value", ".google.protobuf.UInt64Value", ]) + .out_dir(out_dir) .build(&[".google"])?; Ok(()) diff --git a/pbjson-types/src/lib.rs b/pbjson-types/src/lib.rs index caf506a..09511cd 100644 --- a/pbjson-types/src/lib.rs +++ b/pbjson-types/src/lib.rs @@ -27,14 +27,7 @@ clippy::enum_variant_names, clippy::use_self )] -mod pb { - pub mod google { - pub mod protobuf { - include!(concat!(env!("OUT_DIR"), "/google.protobuf.rs")); - include!(concat!(env!("OUT_DIR"), "/google.protobuf.serde.rs")); - } - } -} +mod pb; mod duration; mod list_value; diff --git a/pbjson-types/src/pb/google.protobuf.rs b/pbjson-types/src/pb/google.protobuf.rs new file mode 100644 index 0000000..ae2d4ed --- /dev/null +++ b/pbjson-types/src/pb/google.protobuf.rs @@ -0,0 +1,840 @@ +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Any { + #[prost(string, tag="1")] + pub type_url: ::prost::alloc::string::String, + #[prost(bytes="bytes", tag="2")] + pub value: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct SourceContext { + #[prost(string, tag="1")] + pub file_name: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Type { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(message, repeated, tag="2")] + pub fields: ::prost::alloc::vec::Vec, + #[prost(string, repeated, tag="3")] + pub oneofs: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, + #[prost(message, repeated, tag="4")] + pub options: ::prost::alloc::vec::Vec