Add --list option and ExecutionMode enum to cargo-fuzztest.

- Add ExecutionMode enum with variant ListFuzzTests.
- Add execution_mode() method to CargoFuzzTestOptions returning ExecutionMode::ListFuzzTests.

PiperOrigin-RevId: 964260361
diff --git a/rust/cargo_fuzztest/src/lib.rs b/rust/cargo_fuzztest/src/lib.rs
index cee0743..510cdc0 100644
--- a/rust/cargo_fuzztest/src/lib.rs
+++ b/rust/cargo_fuzztest/src/lib.rs
@@ -22,14 +22,37 @@
 use std::path::{Path, PathBuf};
 use std::process::Command;
 
-#[derive(Parser, Debug, Clone, Default)]
-pub struct CargoFuzzTestOptions {}
-
 fn get_cargo_bin() -> String {
     env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())
 }
 
-/// Queries Cargo via `cargo -vV` to discover the default host target triple (e.g. `x86_64-unknown-linux-gnu`).
+#[derive(Parser, Debug, Clone, Default)]
+pub struct CargoFuzzTestOptions {
+    /// List all fuzz tests in the crate without running them.
+    #[arg(long)]
+    pub list: bool,
+}
+
+impl CargoFuzzTestOptions {
+    /// Returns the active domain `ExecutionMode` derived from CLI options.
+    pub fn execution_mode(&self) -> ExecutionMode {
+        if self.list {
+            return ExecutionMode::ListFuzzTests;
+        }
+        ExecutionMode::SmokeTest
+    }
+}
+
+/// Domain execution mode for `cargo-fuzztest`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ExecutionMode {
+    /// List all discovered fuzz tests without running them.
+    ListFuzzTests,
+
+    SmokeTest,
+}
+
+/// Queries cargo via `cargo -vV` to discover the default host target triple (e.g. `x86_64-unknown-linux-gnu`).
 pub fn get_host_target_triple() -> anyhow::Result<String> {
     let cargo_bin = get_cargo_bin();
     let output = Command::new(&cargo_bin)
@@ -42,7 +65,7 @@
     }
 
     let stdout_str = String::from_utf8(output.stdout)
-        .context("while attempting to parse stdout of cargo -vV as UTF-8")?;
+        .context("while attempting to parse stdout of `cargo -vV` as UTF-8")?;
     parse_host_triple(&stdout_str)
 }
 
@@ -146,13 +169,23 @@
     pub fn build_run_command(&self, test_binary: &Path) -> Command {
         let mut cmd = Command::new(test_binary);
         cmd.arg("__fuzztest_mod__");
-        cmd.arg("--test-threads=1");
+
+        let mode = self.options.execution_mode();
+        match mode {
+            ExecutionMode::ListFuzzTests => {
+                cmd.arg("--list");
+            }
+            ExecutionMode::SmokeTest => {
+                // nothing to be done
+            }
+        }
+
         cmd
     }
 
     /// Runs the tool in two steps:
     /// 1. build the test binary
-    /// 2. run the test binary
+    /// 2. execute the target mode command on the compiled test binary
     pub fn run(&self) -> Result<i32> {
         // 1. build the test binary
         let compile_output = self
@@ -173,7 +206,7 @@
             .context("while attempting to parse compilation JSON output as UTF-8")?;
         let test_binary = Self::parse_compiler_messages(&json_stdout)?;
 
-        // 2. run the test binary
+        // 2. execute command according to the selected execution mode
         let mut run_cmd = self.build_run_command(&test_binary);
         let status =
             run_cmd.status().context("while attempting to execute compiled test binary")?;
@@ -208,4 +241,50 @@
         assert!(result.is_err());
         assert!(result.unwrap_err().to_string().contains("Failed to find 'host: '"));
     }
+
+    #[gtest]
+    fn test_build_run_command_default() {
+        let options = CargoFuzzTestOptions::default();
+        let runner = FuzztestRunner::new("sample-host-triple".to_string(), options);
+        let cmd = runner.build_run_command(Path::new("/tmp/test_bin"));
+        let args: Vec<String> = cmd.get_args().map(|a| a.to_string_lossy().to_string()).collect();
+        assert_eq!(args, &["__fuzztest_mod__"]);
+    }
+
+    #[gtest]
+    fn test_build_run_command_list() {
+        let options = CargoFuzzTestOptions { list: true };
+        let runner = FuzztestRunner::new("sample-host-triple".to_string(), options);
+        let cmd = runner.build_run_command(Path::new("/tmp/test_bin"));
+        let args: Vec<String> = cmd.get_args().map(|a| a.to_string_lossy().to_string()).collect();
+        assert_eq!(args, &["__fuzztest_mod__", "--list"]);
+    }
+
+    #[gtest]
+    fn test_execution_mode_smoke_test() {
+        let options = CargoFuzzTestOptions { list: false };
+        assert_eq!(options.execution_mode(), ExecutionMode::SmokeTest);
+    }
+
+    #[gtest]
+    fn test_execution_mode_list_fuzz_tests() {
+        let options = CargoFuzzTestOptions { list: true };
+        assert_eq!(options.execution_mode(), ExecutionMode::ListFuzzTests);
+    }
+
+    #[gtest]
+    fn test_cli_option_parsing_list_flag() {
+        let parsed = CargoFuzzTestOptions::try_parse_from(["cargo-fuzztest", "--list"])
+            .expect("--list argument should be valid CLI option");
+        assert!(parsed.list);
+        assert_eq!(parsed.execution_mode(), ExecutionMode::ListFuzzTests);
+    }
+
+    #[gtest]
+    fn test_cli_option_parsing_default() {
+        let parsed = CargoFuzzTestOptions::try_parse_from(["cargo-fuzztest"])
+            .expect("empty CLI arguments should be valid");
+        assert!(!parsed.list);
+        assert_eq!(parsed.execution_mode(), ExecutionMode::SmokeTest);
+    }
 }