rules-proto-grpc / rules_proto_grpc

Bazel rules for building Protobuf and gRPC code and libraries from proto_library targets
https://rules-proto-grpc.com
Apache License 2.0
250 stars 157 forks source link

Rust prost tonic #265

Closed echochamber closed 1 year ago

echochamber commented 1 year ago

Status: It works!


Updated version of @titanous PR https://github.com/rules-proto-grpc/rules_proto_grpc/pull/202.

Users will need to manually declare the declared_proto_packages=["proto.package.name", ...]. The compile rule also requires the crate_name=my_crate be provided (but the macros take care of this part for you).

However, with this information the custom rule implementation will handle creating all the necessary --externs_path=.proto.package.name=::my_create::proto::package::name mappings for you (prost docs).

Things I've tested on both rust_prost_proto_library and rust_tonic_grpc_library:

Known limitations:

echochamber commented 1 year ago

@aaliddell The majority of the logic here is done and ready for review/initial feedback. All of the targets in rust/example/ should build and run just fine.

I'm still working on getting the rules to work outside of the main rules_proto_grpc Workspace. Currently getting an error when I try to bazel build //:thing_rust_proto in the example/rust/rust_prost_proto_compile/WORKSPACE.

external/rules_proto_grpc/rust/3rdparty/crates/BUILD.bazel:161:6: no such package '@rules_proto_grpc_rust__protoc-gen-prost-serde-0.2.3//': The repository '@rules_proto_grpc_rust__protoc-gen-prost-serde-0.2.3' could not be resolved: Repository '@rules_proto_grpc_rust__protoc-gen-prost-serde-0.2.3' is not defined and referenced by '@rules_proto_grpc//rust/3rdparty/crates:protoc-gen-prost-serde__protoc-gen-prost-serde'

echochamber commented 1 year ago

And it works! All of the examples build and run smoothly.

That said, there is something interesting going on with deriving the hash/eq type for the pbjson types.

  1. Thing currently cannot have hash derived because ::pbjson_types::Any doesn't implement Hash.
  2. Attempting to derive Hash on Place (which depends upon thing) causes Prost to also attempt to derive Hash for Thing (since one of the fields in Place is an instance of Option.
  3. This causes a build failure.

However this only occurs in this second example code snippet below, in the first the build succeeds (even though Thing doesn't derive Hash in the generated code), which is interesting.

This builds ```python rust_tonic_grpc_library( name = "greeter_tonic", declared_proto_packages = ["example.proto"], protos = [ "@rules_proto_grpc//example/proto:greeter_grpc", "@rules_proto_grpc//example/proto:person_proto", "@rules_proto_grpc//example/proto:place_proto", ], options = { "//rust:rust_prost_plugin": [ "type_attribute=.example.proto.Person=#[derive(Eq\\,Hash)]", "type_attribute=.example.proto.Place=#[derive(Eq\\,Hash)]", ]}, prost_proto_deps = [ ":thing_prost" ] ) rust_prost_proto_library( name = "thing_prost", declared_proto_packages = ["example.proto"], protos = [ "@rules_proto_grpc//example/proto:thing_proto", ], ) ```
This doesn't build ```python rust_tonic_grpc_library( name = "greeter_tonic", declared_proto_packages = ["example.proto"], protos = [ "@rules_proto_grpc//example/proto:greeter_grpc", "@rules_proto_grpc//example/proto:person_proto", "@rules_proto_grpc//example/proto:place_proto", "@rules_proto_grpc//example/proto:thing_proto", ], options = { "//rust:rust_prost_plugin": [ "type_attribute=.example.proto.Person=#[derive(Eq\\,Hash)]", "type_attribute=.example.proto.Place=#[derive(Eq\\,Hash)]", ]}, ) ```
build error ``` error[E0277]: the trait bound `Thing: Hash` is not satisfied --> bazel-out/k8-fastbuild/bin/greeter_tonic_pb_fixed/example.proto.rs:17:5 | 10 | #[derive(Eq, Hash)] | ---- in this derive macro expansion ... 17 | pub thing: ::core::option::Option, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Hash` is not implemented for `Thing` | = help: the trait `Hash` is implemented for `std::option::Option` = note: required for `std::option::Option` to implement `Hash` = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) ```
aaliddell commented 1 year ago

Ok, time for me to get reading. Thankfully most of those 20,000 lines changed are just raze -> crate_universe :scream:

I'm trying to think if there's any tricks we can play with an aspect that'd let us discover the externs automatically

aaliddell commented 1 year ago

As an update of where I am with this:

I'll start adding commits here as I do the above

aaliddell commented 1 year ago

I've spun the aspect investigation off into #282 as future work, so it doesn't hold this up any further. The rest is now passing with rulegen aligned with your work. Sorry it's taken me so long