4

I have some generated .rs code (from grpc proto files) and they are checked in with my normal Rust code under src but in some sub modules. The issue is that when doing cargo test the doc test will run and some of the generated .rs have comments with indentations (code blocks) and cargo doc test will try to compile them and fail.

For example cargo test will try to compile (and perhaps run these lines) show here.

Is there a way to exclude or ignore those generated .rs for doc test (without manually changing them)?

Kevin Reid
  • 37,492
  • 13
  • 80
  • 108
Fuyang Liu
  • 1,496
  • 13
  • 26
  • 1
    I see you've already updated your linked example with text-fences and from what I can tell ([1](https://stackoverflow.com/q/32429369), [2](https://stackoverflow.com/q/50312190), [3](https://stackoverflow.com/q/38292741)), there doesn't seem to be a way without modifying the documentation. I would've figured you could work around it by conditional `#[doc(hidden)]` but `cargo test` seems to run them regardless. – kmdreko Feb 08 '21 at 04:27
  • Probably for the best though, without the text-fences, it might render improperly when browsing the `cargo doc`s. – kmdreko Feb 08 '21 at 04:30

1 Answers1

0

Updated answer:

I have hacked together a crate tonic-disable-doctest for disabling doctests, it may be used as such:

use tonic_disable_doctest::BuilderEx;

fn main() {
    tonic_build::configure()
        .disable_doctests_for_types([".google.api.HttpRule"])
        .compile(
            &["proto/api/google/api/http.proto"],
            &["proto/"],
        )
        .unwrap();
}

Old answer

My solution

I've resolved this by injecting code that separates the offending comment and the structure underneath:

fn main() {
    tonic_build::configure()
        .type_attribute(
            ".google.api.HttpRule",
            "#[cfg(not(doctest))]\n\
             #[allow(dead_code)]\n\
             pub struct HttpRuleComment{}\n\
             /// HACK: see docs in [`HttpRuleComment`] ignored in doctest pass",
        )
        .compile(
            &["proto/api/google/api/http.proto"],
            &["proto/"],
        )
        .unwrap();
}
Explanation:
  1. tonic_build allows adding attributes to specific protobuf paths, but it does not discern between attributes or any other strings.
  2. #[cfg(not(doctest))] excludes the comment's offending code from doc tests, because it excludes the structure it's added to, this trick is taken from discussion on Rust user forum.
  3. #[allow(dead_code)] silences warnings about injected structure not being used (as it shouldn't be used).
  4. pub struct HttpRuleComment{} creates a public structure that can be referenced in the docstring for the original struct.
  5. /// ...[HttpRuleComment]... is a docstring referencing injected struct, so that the original documentation can still be accessed.
Notes:

I'm not sure if your case is the same, but I found myself on this SO page a lot while searching for an answer and decided to share the results.

In my case, the only offending comment was in HttpRule, you may need to write a macro or do lots of copy-paste if you happen to have multiple offending comments.

sukhmel
  • 1,402
  • 16
  • 29
  • 1
    Aha, thank you, I am also using tonic_build, and the issue was also related to some google API protos (some bigtable proto to be more specific). So perhaps this can work for my case. – Fuyang Liu Mar 23 '23 at 17:16
  • @FuyangLiu you may mark this as the answer if it worked or provide some more input as to what went wrong. – sukhmel May 23 '23 at 13:59
  • Thanks, I need to find time to test it, but I feel your solution is not very generic and needs some tweaks for each scenario? – Fuyang Liu May 24 '23 at 14:30
  • I thought that it makes more sense to publish it as a crate =) edited the answer – sukhmel May 25 '23 at 11:23