Automatically generate rust tests and doctests

Change-Id: I685d6905d8861aa3368c46eda0e783497e88b581
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/tools/build_rules/autocxx.bzl b/tools/build_rules/autocxx.bzl
index 4046068..5cadf2b 100644
--- a/tools/build_rules/autocxx.bzl
+++ b/tools/build_rules/autocxx.bzl
@@ -252,7 +252,7 @@
         crate_features = None,
         crate_name = None,
         gen_debug = None,
-        docs = True):
+        **kwargs):
     """A macro to generate Rust <-> C++ interop code with autocxx.
 
     Creates the following rules:
@@ -344,5 +344,5 @@
         ],
         compile_data = [gen_compile_data_name],
         rustc_env_files = [gen_env_files_name],
-        docs = docs,
+        **kwargs
     )
diff --git a/tools/rust/defs.bzl b/tools/rust/defs.bzl
index ba58294..88caca5 100644
--- a/tools/rust/defs.bzl
+++ b/tools/rust/defs.bzl
@@ -36,23 +36,6 @@
         **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"],
-            target_compatible_with = ["//tools/platforms/rust:has_support"],
-            rustdoc_flags = ["--document-private-items", "-Dwarnings"],
-        )
-
 def rust_test(target_compatible_with = ["//tools/platforms/rust:has_support"], rustc_flags = [], **kwargs):
     _rust_test(
         target_compatible_with = select({
@@ -63,6 +46,56 @@
         **kwargs
     )
 
+def rust_library(
+        name,
+        target_compatible_with = ["//tools/platforms/rust:has_support"],
+        gen_docs = True,
+        gen_tests = True,
+        gen_doctests = True,
+        **kwargs):
+    test_params = {}
+    doctest_params = {}
+    params = {}
+
+    for (param, value) in kwargs.items():
+        if param.startswith("test_"):
+            test_params[param[5:]] = value
+        elif param.startswith("doctest_"):
+            doctest_params[param[8:]] = value
+        else:
+            params[param] = value
+
+    _rust_library(
+        name = name,
+        target_compatible_with = select({
+            Label("//conditions:default"): target_compatible_with,
+            Label("//tools:has_msan"): ["@platforms//:incompatible"],
+        }),
+        **params
+    )
+
+    if gen_tests:
+        rust_test(
+            name = name + "_test",
+            crate = name,
+            **test_params
+        )
+
+    if gen_docs:
+        rust_doc(
+            name = name + "_doc",
+            crate = name,
+            target_compatible_with = ["//tools/platforms/rust:has_support"],
+            rustdoc_flags = ["--document-private-items", "-Dwarnings"],
+        )
+
+    if gen_doctests:
+        rust_doc_test(
+            name = name + "_doctest",
+            crate = name,
+            **doctest_params
+        )
+
 def flatbuffer_rust_library(target_compatible_with = ["//tools/platforms/rust:has_support"], **kwargs):
     _flatbuffer_rust_library(
         target_compatible_with = select({