Automatically document all rust crates

Additionally, add a ./dev_tools/cargo-doc.sh script that builds and
opens the documentation for any documented rust target.

Change-Id: I2a52adaf90ca93cb749415260c02f3777a53ddf6
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/tools/build_rules/autocxx.bzl b/tools/build_rules/autocxx.bzl
index c17c5e2..4046068 100644
--- a/tools/build_rules/autocxx.bzl
+++ b/tools/build_rules/autocxx.bzl
@@ -251,7 +251,8 @@
         testonly = None,
         crate_features = None,
         crate_name = None,
-        gen_debug = None):
+        gen_debug = None,
+        docs = True):
     """A macro to generate Rust <-> C++ interop code with autocxx.
 
     Creates the following rules:
@@ -343,4 +344,5 @@
         ],
         compile_data = [gen_compile_data_name],
         rustc_env_files = [gen_env_files_name],
+        docs = docs,
     )
diff --git a/tools/rust/defs.bzl b/tools/rust/defs.bzl
index 9c17d93..6eb2cdb 100644
--- a/tools/rust/defs.bzl
+++ b/tools/rust/defs.bzl
@@ -8,37 +8,6 @@
 )
 load("@com_github_google_flatbuffers//:build_defs.bzl", _flatbuffer_rust_library = "flatbuffer_rust_library")
 
-def rust_binary(target_compatible_with = ["//tools/platforms/rust:has_support"], rustc_flags = [], **kwargs):
-    _rust_binary(
-        target_compatible_with = select({
-            Label("//conditions:default"): target_compatible_with,
-            Label("//tools:has_msan"): ["@platforms//:incompatible"],
-        }),
-        # TODO: Make Rust play happy with pic vs nopic. Details at:
-        # https://github.com/bazelbuild/rules_rust/issues/118
-        rustc_flags = rustc_flags + ["-Crelocation-model=static"],
-        **kwargs
-    )
-
-def rust_library(target_compatible_with = ["//tools/platforms/rust:has_support"], **kwargs):
-    _rust_library(
-        target_compatible_with = select({
-            Label("//conditions:default"): target_compatible_with,
-            Label("//tools:has_msan"): ["@platforms//:incompatible"],
-        }),
-        **kwargs
-    )
-
-def rust_test(target_compatible_with = ["//tools/platforms/rust:has_support"], rustc_flags = [], **kwargs):
-    _rust_test(
-        target_compatible_with = select({
-            Label("//conditions:default"): target_compatible_with,
-            Label("//tools:has_msan"): ["@platforms//:incompatible"],
-        }),
-        rustc_flags = rustc_flags + ["-Crelocation-model=static"],
-        **kwargs
-    )
-
 def rust_doc_test(target_compatible_with = ["//tools/platforms/rust:has_support"], tags = [], **kwargs):
     # TODO(james): Attempting to execute this remotely results
     # in complaints about overly large files.
@@ -54,6 +23,45 @@
         **kwargs
     )
 
+def rust_binary(target_compatible_with = ["//tools/platforms/rust:has_support"], rustc_flags = [], **kwargs):
+    _rust_binary(
+        target_compatible_with = select({
+            Label("//conditions:default"): target_compatible_with,
+            Label("//tools:has_msan"): ["@platforms//:incompatible"],
+        }),
+        # TODO: Make Rust play happy with pic vs nopic. Details at:
+        # https://github.com/bazelbuild/rules_rust/issues/118
+        rustc_flags = rustc_flags + ["-Crelocation-model=static"],
+        **kwargs
+    )
+
+def rust_library(target_compatible_with = ["//tools/platforms/rust:has_support"], docs = True, **kwargs):
+    _rust_library(
+        target_compatible_with = select({
+            Label("//conditions:default"): target_compatible_with,
+            Label("//tools:has_msan"): ["@platforms//:incompatible"],
+        }),
+        **kwargs
+    )
+
+    if docs:
+        rust_doc(
+            name = kwargs["name"] + "_doc",
+            crate = kwargs["name"],
+            rustdoc_flags = ["--document-private-items"],
+            target_compatible_with = ["//tools/platforms/rust:has_support"],
+        )
+
+def rust_test(target_compatible_with = ["//tools/platforms/rust:has_support"], rustc_flags = [], **kwargs):
+    _rust_test(
+        target_compatible_with = select({
+            Label("//conditions:default"): target_compatible_with,
+            Label("//tools:has_msan"): ["@platforms//:incompatible"],
+        }),
+        rustc_flags = rustc_flags + ["-Crelocation-model=static"],
+        **kwargs
+    )
+
 def flatbuffer_rust_library(target_compatible_with = ["//tools/platforms/rust:has_support"], **kwargs):
     _flatbuffer_rust_library(
         target_compatible_with = select({