hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
10.02k stars 1.02k forks source link

Add ability to specify import path instead of hardcode to `tonic-build` codegen #699

Open ghost opened 3 years ago

ghost commented 3 years ago

Feature Request

Add ability to specify path to tonic and async_trait imports when referenced in codegen.

Crates

tonic-build

Motivation

I keep tonic and many other dependencies in a separate package. When I import them into a package that uses tonic-build to generate Rust proto, I get an error saying tonic and async_trait cannot be found.

Currently, the only way to use tonic is a direct dependency of the main package not as an import from another package. I haven't come across this issue with other packages. Serde has "crate" container attribute that solves theirs.

Proposal

Add a new method to the tonic_build::configure() -> Config Builder trait.

Alternatives

The alternative way is I clone the repo and hardcode the correct import path.

davidpdrsn commented 3 years ago

I don't follow. Why can't you depend on tonic for the crate that includes the compiled protos?

ghost commented 3 years ago

If I import tonic and prost from another package, the codegen does not find the modules image

However, if I include tonic and prost in the same package that compiles protos, it works image

I don't know why that is.

davidpdrsn commented 3 years ago

I suppose that is because the client and server codegen nests things in modules. See https://github.com/hyperium/tonic/blob/master/tonic-build/src/server.rs#L67 and https://github.com/hyperium/tonic/blob/master/tonic-build/src/client.rs#L25.

I wonder if adding use super::* to the generated modules would fix it or if a crate config similar to serde's is necessary.

ghost commented 3 years ago

Yes if I refer to tonic as crate::tonic::codegen::*, it works but prost doesn't. It uses :: (https://github.com/tokio-rs/prost/blob/master/prost-build/src/code_generator.rs#L177) which isn't going to work in this Rust-2018 project according to https://doc.rust-lang.org/reference/visibility-and-privacy.html#pubin-path-pubcrate-pubsuper-and-pubself

LucioFranco commented 3 years ago

Do you have a simple reproduction of your issue? I am not totally following what the issue is.

JSAbrahams commented 1 month ago

Just chiming in, a use case for this I think is also avoiding have to align tonic versions across many crates. Say I have the following:

Now, if I wish to update the tonic version in util, I have to make sure that crate A and crate B's versions are also aligned. A much more elegant solution would be if I could just depend on the re-export tonic from util as such use util::tonic (in say crate A). But since tonic_build outputs files where tonic:: is hardcoded, the compiler does not allow this.

In this example, ideally, I would like to be able to tell tonic_build to output files which use util::tonic, for instance.