Automatically generate rust tests and doctests

Change-Id: I685d6905d8861aa3368c46eda0e783497e88b581
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/BUILD b/aos/BUILD
index d9781f9..38f3cf6 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -3,7 +3,7 @@
 load("@com_github_google_flatbuffers//:typescript.bzl", "flatbuffer_ts_library")
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
-load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_library", "rust_test")
+load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_library")
 
 exports_files(["aos_dump_autocomplete.sh"])
 
@@ -215,17 +215,12 @@
     ],
 )
 
-rust_test(
-    name = "init_rs_test",
-    crate = ":init_rs",
-)
-
 autocxx_library(
     name = "test_init_rs",
     testonly = True,
     srcs = ["test_init.rs"],
     crate_name = "aos_test_init",
-    docs = False,
+    gen_docs = False,
     libs = [
         "//aos/testing:tmpdir",
     ],
@@ -346,6 +341,9 @@
         ":configuration_fbs",
     ],
     override_cc_toolchain = "@llvm_toolchain//:cc-clang-x86_64-linux",
+    test_data = [
+        "//aos/testdata:test_configs",
+    ],
     visibility = ["//visibility:public"],
     deps = [
         ":configuration_rust_fbs",
@@ -354,14 +352,6 @@
     ],
 )
 
-rust_test(
-    name = "configuration_rs_test",
-    crate = ":configuration_rs",
-    data = [
-        "//aos/testdata:test_configs",
-    ],
-)
-
 flatbuffer_ts_library(
     name = "json_to_flatbuffer_fbs_ts",
     srcs = ["json_to_flatbuffer.fbs"],
@@ -521,20 +511,15 @@
     name = "flatbuffers_rs",
     srcs = ["flatbuffers.rs"],
     crate_name = "aos_flatbuffers",
+    test_deps = [
+        ":json_to_flatbuffer_rust_fbs",
+    ],
     visibility = ["//visibility:public"],
     deps = [
         "@com_github_google_flatbuffers//rust",
     ],
 )
 
-rust_test(
-    name = "flatbuffers_rs_test",
-    crate = ":flatbuffers_rs",
-    deps = [
-        ":json_to_flatbuffer_rust_fbs",
-    ],
-)
-
 cc_test(
     name = "configuration_test",
     srcs = [
diff --git a/aos/events/BUILD b/aos/events/BUILD
index 015c316..2793195 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -3,7 +3,7 @@
 load("//aos:flatbuffers.bzl", "cc_static_flatbuffer")
 load("//aos:config.bzl", "aos_config")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
-load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_binary", "rust_doc_test", "rust_library", "rust_test")
+load("//tools/rust:defs.bzl", "flatbuffer_rust_library", "rust_binary", "rust_library", "rust_test")
 
 package(default_visibility = ["//visibility:public"])
 
@@ -146,6 +146,10 @@
     name = "event_loop_runtime",
     srcs = ["event_loop_runtime.rs"],
     crate_name = "aos_events_event_loop_runtime",
+    doctest_deps = [
+        ":pong_rust_fbs",
+    ],
+    gen_tests = False,
     libs = [
         ":event_loop_runtime_cc",
     ],
@@ -163,20 +167,11 @@
     ],
 )
 
-rust_doc_test(
-    name = "event_loop_runtime_doc_test",
-    crate = ":event_loop_runtime",
-    target_compatible_with = ["@platforms//cpu:x86_64"],
-    deps = [
-        ":pong_rust_fbs",
-    ],
-)
-
 autocxx_library(
     name = "event_loop_runtime_test_lib_rs",
     testonly = True,
     srcs = ["event_loop_runtime_test_lib.rs"],
-    docs = False,
+    gen_docs = False,
     libs = [
         ":event_loop",
     ],
@@ -618,6 +613,15 @@
         "//aos:flatbuffers_rs",
         "@crate_index//:futures",
     ],
+    test_data = [
+        ":multinode_pingpong_test_combined_config",
+    ],
+    test_deps = [
+        ":ping_rust_fbs",
+        "//aos:test_init_rs",
+        "@crate_index//:futures",
+        "@rules_rust//tools/runfiles",
+    ],
     visibility = ["//visibility:public"],
     deps = [
         ":event_loop_runtime",
@@ -626,24 +630,14 @@
     ],
 )
 
-rust_test(
-    name = "simulated_event_loop_rs_test",
-    crate = ":simulated_event_loop_rs",
-    data = [
-        ":multinode_pingpong_test_combined_config",
-    ],
-    deps = [
-        ":ping_rust_fbs",
-        "//aos:test_init_rs",
-        "@crate_index//:futures",
-        "@rules_rust//tools/runfiles",
-    ],
-)
-
 autocxx_library(
     name = "shm_event_loop_rs",
     srcs = ["shm_event_loop.rs"],
     crate_name = "aos_events_shm_event_loop",
+    doctest_deps = [
+        ":ping_rust_fbs",
+        ":pong_rust_fbs",
+    ],
     libs = [
         ":shm_event_loop",
         ":shm_event_loop_for_rust",
@@ -654,32 +648,17 @@
         "//aos:configuration_rust_fbs",
         "//aos:flatbuffers_rs",
     ],
-    visibility = ["//visibility:public"],
-    deps = [
-        ":event_loop_runtime",
-        "//aos:configuration_rs",
-    ],
-)
-
-rust_test(
-    name = "shm_event_loop_rs_test",
-    crate = ":shm_event_loop_rs",
-    data = [":pingpong_config"],
-    deps = [
+    test_data = [":pingpong_config"],
+    test_deps = [
         ":ping_rust_fbs",
         "//aos:test_init_rs",
         "@crate_index//:futures",
         "@rules_rust//tools/runfiles",
     ],
-)
-
-rust_doc_test(
-    name = "shm_event_loop_rs_doc_test",
-    crate = ":shm_event_loop_rs",
-    target_compatible_with = ["@platforms//cpu:x86_64"],
+    visibility = ["//visibility:public"],
     deps = [
-        ":ping_rust_fbs",
-        ":pong_rust_fbs",
+        ":event_loop_runtime",
+        "//aos:configuration_rs",
     ],
 )
 
diff --git a/build_tests/BUILD b/build_tests/BUILD
index f0ff94d..282365e 100644
--- a/build_tests/BUILD
+++ b/build_tests/BUILD
@@ -4,7 +4,7 @@
 load("@com_github_google_flatbuffers//:build_defs.bzl", "flatbuffer_go_library", "flatbuffer_py_library")
 load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
 load("//tools/build_rules:apache.bzl", "apache_wrapper")
-load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")
+load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library")
 load("//tools/build_rules:autocxx.bzl", "autocxx_library")
 
 cc_test(
@@ -153,12 +153,6 @@
     target_compatible_with = ["//tools/platforms/rust:has_support"],
 )
 
-rust_test(
-    name = "hello_lib_test",
-    crate = ":hello_lib",
-    target_compatible_with = ["//tools/platforms/rust:has_support"],
-)
-
 rust_binary(
     name = "rust_hello",
     srcs = ["rust_hello.rs"],
@@ -199,15 +193,6 @@
     target_compatible_with = ["//tools/platforms/rust:has_support"],
 )
 
-rust_test(
-    name = "hello_autocxx_test",
-    crate = ":hello_autocxx",
-    # TODO: Make Rust play happy with pic vs nopic. Details at:
-    # https://github.com/bazelbuild/rules_rust/issues/118
-    rustc_flags = ["-Crelocation-model=static"],
-    target_compatible_with = ["//tools/platforms/rust:has_support"],
-)
-
 py_test(
     name = "upstream_python_test",
     srcs = [
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({