No public description

PiperOrigin-RevId: 956747198
diff --git a/.bazelrc b/.bazelrc
index 19ff5f5..9710195 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -44,3 +44,9 @@
 #  bazel run //bazel:setup_configs > fuzztest.bazelrc
 #
 try-import %workspace%/fuzztest.bazelrc
+
+# Configure rules_rust to use the nightly channel toolchain by default.
+build --@rules_rust//rust/toolchain/channel:channel=nightly
+
+# Link standard C++ library for Rust binaries on Linux
+# build:linux --linkopt=-lstdc++
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..7627798
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1 @@
+exports_files(["MODULE.bazel"])
diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock
new file mode 100644
index 0000000..f6ba62b
--- /dev/null
+++ b/Cargo.Bazel.lock
@@ -0,0 +1,5895 @@
+{
+  "checksum": "7fe8e06bf5d789f55dfeac6f39f71119f0acdbe34a8356c5c3d64f9ffb0e9d1e",
+  "crates": {
+    "aho-corasick 1.1.4": {
+      "name": "aho-corasick",
+      "version": "1.1.4",
+      "package_url": "https://github.com/BurntSushi/aho-corasick",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/aho-corasick/1.1.4/download",
+          "sha256": "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "aho_corasick",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "aho_corasick",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "perf-literal",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "memchr 2.8.3",
+              "target": "memchr"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.1.4"
+      },
+      "license": "Unlicense OR MIT",
+      "license_ids": [
+        "MIT",
+        "Unlicense"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "anstream 1.0.0": {
+      "name": "anstream",
+      "version": "1.0.0",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anstream/1.0.0/download",
+          "sha256": "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anstream",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anstream",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "auto",
+            "default",
+            "wincon"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "anstyle 1.0.14",
+              "target": "anstyle"
+            },
+            {
+              "id": "anstyle-parse 1.0.0",
+              "target": "anstyle_parse"
+            },
+            {
+              "id": "anstyle-query 1.1.5",
+              "target": "anstyle_query"
+            },
+            {
+              "id": "colorchoice 1.0.5",
+              "target": "colorchoice"
+            },
+            {
+              "id": "is_terminal_polyfill 1.70.2",
+              "target": "is_terminal_polyfill"
+            },
+            {
+              "id": "utf8parse 0.2.2",
+              "target": "utf8parse"
+            }
+          ],
+          "selects": {
+            "x86_64-pc-windows-msvc": [
+              {
+                "id": "anstyle-wincon 3.0.11",
+                "target": "anstyle_wincon"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "1.0.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "anstyle 1.0.14": {
+      "name": "anstyle",
+      "version": "1.0.14",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anstyle/1.0.14/download",
+          "sha256": "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anstyle",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anstyle",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.14"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "anstyle-parse 1.0.0": {
+      "name": "anstyle-parse",
+      "version": "1.0.0",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anstyle-parse/1.0.0/download",
+          "sha256": "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anstyle_parse",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anstyle_parse",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "utf8"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "utf8parse 0.2.2",
+              "target": "utf8parse"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "anstyle-query 1.1.5": {
+      "name": "anstyle-query",
+      "version": "1.1.5",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anstyle-query/1.1.5/download",
+          "sha256": "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anstyle_query",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anstyle_query",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [],
+          "selects": {
+            "cfg(windows)": [
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "1.1.5"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "anstyle-wincon 3.0.11": {
+      "name": "anstyle-wincon",
+      "version": "3.0.11",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anstyle-wincon/3.0.11/download",
+          "sha256": "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anstyle_wincon",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anstyle_wincon",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "anstyle 1.0.14",
+              "target": "anstyle"
+            }
+          ],
+          "selects": {
+            "cfg(windows)": [
+              {
+                "id": "once_cell_polyfill 1.70.2",
+                "target": "once_cell_polyfill"
+              },
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "3.0.11"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "anyhow 1.0.104": {
+      "name": "anyhow",
+      "version": "1.0.104",
+      "package_url": "https://github.com/dtolnay/anyhow",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/anyhow/1.0.104/download",
+          "sha256": "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "anyhow",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "anyhow",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "anyhow 1.0.104",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.104"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "atomic-polyfill 1.0.3": {
+      "name": "atomic-polyfill",
+      "version": "1.0.3",
+      "package_url": "https://github.com/embassy-rs/atomic-polyfill",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/atomic-polyfill/1.0.3/download",
+          "sha256": "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "atomic_polyfill",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "atomic_polyfill",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "atomic-polyfill 1.0.3",
+              "target": "build_script_build"
+            },
+            {
+              "id": "critical-section 1.2.0",
+              "target": "critical_section"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.3"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "autocfg 1.5.1": {
+      "name": "autocfg",
+      "version": "1.5.1",
+      "package_url": "https://github.com/cuviper/autocfg",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/autocfg/1.5.1/download",
+          "sha256": "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "autocfg",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "autocfg",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2015",
+        "version": "1.5.1"
+      },
+      "license": "Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "bitflags 2.13.1": {
+      "name": "bitflags",
+      "version": "2.13.1",
+      "package_url": "https://github.com/bitflags/bitflags",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/bitflags/2.13.1/download",
+          "sha256": "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "bitflags",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "bitflags",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "2.13.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "byteorder 1.5.0": {
+      "name": "byteorder",
+      "version": "1.5.0",
+      "package_url": "https://github.com/BurntSushi/byteorder",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/byteorder/1.5.0/download",
+          "sha256": "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "byteorder",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "byteorder",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "1.5.0"
+      },
+      "license": "Unlicense OR MIT",
+      "license_ids": [
+        "MIT",
+        "Unlicense"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "cfg-if 1.0.4": {
+      "name": "cfg-if",
+      "version": "1.0.4",
+      "package_url": "https://github.com/rust-lang/cfg-if",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/cfg-if/1.0.4/download",
+          "sha256": "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "cfg_if",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "cfg_if",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2018",
+        "version": "1.0.4"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "chacha20 0.10.1": {
+      "name": "chacha20",
+      "version": "0.10.1",
+      "package_url": "https://github.com/RustCrypto/stream-ciphers",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/chacha20/0.10.1/download",
+          "sha256": "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "chacha20",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "chacha20",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "rng"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "cfg-if 1.0.4",
+              "target": "cfg_if"
+            },
+            {
+              "id": "rand_core 0.10.1",
+              "target": "rand_core"
+            }
+          ],
+          "selects": {
+            "cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))": [
+              {
+                "id": "cpufeatures 0.3.0",
+                "target": "cpufeatures"
+              }
+            ]
+          }
+        },
+        "edition": "2024",
+        "version": "0.10.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "clap 4.6.4": {
+      "name": "clap",
+      "version": "4.6.4",
+      "package_url": "https://github.com/clap-rs/clap",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/clap/4.6.4/download",
+          "sha256": "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "clap",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "clap",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "color",
+            "default",
+            "derive",
+            "env",
+            "error-context",
+            "help",
+            "std",
+            "suggestions",
+            "usage"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "clap_builder 4.6.2",
+              "target": "clap_builder"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "proc_macro_deps": {
+          "common": [
+            {
+              "id": "clap_derive 4.6.4",
+              "target": "clap_derive"
+            }
+          ],
+          "selects": {}
+        },
+        "version": "4.6.4"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "clap_builder 4.6.2": {
+      "name": "clap_builder",
+      "version": "4.6.2",
+      "package_url": "https://github.com/clap-rs/clap",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/clap_builder/4.6.2/download",
+          "sha256": "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "clap_builder",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "clap_builder",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "color",
+            "env",
+            "error-context",
+            "help",
+            "std",
+            "suggestions",
+            "usage"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "anstream 1.0.0",
+              "target": "anstream"
+            },
+            {
+              "id": "anstyle 1.0.14",
+              "target": "anstyle"
+            },
+            {
+              "id": "clap_lex 1.1.0",
+              "target": "clap_lex"
+            },
+            {
+              "id": "strsim 0.11.1",
+              "target": "strsim"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "4.6.2"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "clap_derive 4.6.4": {
+      "name": "clap_derive",
+      "version": "4.6.4",
+      "package_url": "https://github.com/clap-rs/clap",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/clap_derive/4.6.4/download",
+          "sha256": "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
+        }
+      },
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "clap_derive",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "clap_derive",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "heck 0.5.0",
+              "target": "heck"
+            },
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "syn 3.0.3",
+              "target": "syn"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "4.6.4"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "clap_lex 1.1.0": {
+      "name": "clap_lex",
+      "version": "1.1.0",
+      "package_url": "https://github.com/clap-rs/clap",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/clap_lex/1.1.0/download",
+          "sha256": "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "clap_lex",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "clap_lex",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2024",
+        "version": "1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "cobs 0.3.0": {
+      "name": "cobs",
+      "version": "0.3.0",
+      "package_url": "https://github.com/jamesmunns/cobs.rs",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/cobs/0.3.0/download",
+          "sha256": "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "cobs",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "cobs",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "thiserror 2.0.19",
+              "target": "thiserror"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.3.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "colorchoice 1.0.5": {
+      "name": "colorchoice",
+      "version": "1.0.5",
+      "package_url": "https://github.com/rust-cli/anstyle.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/colorchoice/1.0.5/download",
+          "sha256": "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "colorchoice",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "colorchoice",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "1.0.5"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "convert_case 0.4.0": {
+      "name": "convert_case",
+      "version": "0.4.0",
+      "package_url": "https://github.com/rutrum/convert-case",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/convert_case/0.4.0/download",
+          "sha256": "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "convert_case",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "convert_case",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2018",
+        "version": "0.4.0"
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": null
+    },
+    "coverage 0.1.0": {
+      "name": "coverage",
+      "version": "0.1.0",
+      "package_url": null,
+      "repository": null,
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "coverage",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "coverage",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2024",
+        "version": "0.1.0"
+      },
+      "license": null,
+      "license_ids": [],
+      "license_file": null
+    },
+    "cpufeatures 0.3.0": {
+      "name": "cpufeatures",
+      "version": "0.3.0",
+      "package_url": "https://github.com/RustCrypto/utils",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/cpufeatures/0.3.0/download",
+          "sha256": "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "cpufeatures",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "cpufeatures",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [],
+          "selects": {
+            "cfg(all(target_arch = \"aarch64\", target_os = \"android\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ]
+          }
+        },
+        "edition": "2024",
+        "version": "0.3.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "critical-section 1.2.0": {
+      "name": "critical-section",
+      "version": "1.2.0",
+      "package_url": "https://github.com/rust-embedded/critical-section",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/critical-section/1.2.0/download",
+          "sha256": "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "critical_section",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "critical_section",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2018",
+        "version": "1.2.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "dissimilar 1.0.11": {
+      "name": "dissimilar",
+      "version": "1.0.11",
+      "package_url": "https://github.com/dtolnay/dissimilar",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/dissimilar/1.0.11/download",
+          "sha256": "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "dissimilar",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "dissimilar",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "1.0.11"
+      },
+      "license": "Apache-2.0",
+      "license_ids": [
+        "Apache-2.0"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "embedded-io 0.4.0": {
+      "name": "embedded-io",
+      "version": "0.4.0",
+      "package_url": "https://github.com/embassy-rs/embedded-io",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/embedded-io/0.4.0/download",
+          "sha256": "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "embedded_io",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "embedded_io",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "0.4.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "embedded-io 0.6.1": {
+      "name": "embedded-io",
+      "version": "0.6.1",
+      "package_url": "https://github.com/rust-embedded/embedded-hal",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/embedded-io/0.6.1/download",
+          "sha256": "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "embedded_io",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "embedded_io",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "0.6.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "engine-ffi 0.1.0": {
+      "name": "engine-ffi",
+      "version": "0.1.0",
+      "package_url": null,
+      "repository": null,
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "engine_ffi",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "engine_ffi",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "engine-ffi 0.1.0",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "0.1.0"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ],
+        "links": "centipede_engine_static"
+      },
+      "license": null,
+      "license_ids": [],
+      "license_file": null
+    },
+    "equivalent 1.0.2": {
+      "name": "equivalent",
+      "version": "1.0.2",
+      "package_url": "https://github.com/indexmap-rs/equivalent",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/equivalent/1.0.2/download",
+          "sha256": "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "equivalent",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "equivalent",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2015",
+        "version": "1.0.2"
+      },
+      "license": "Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "errno 0.3.14": {
+      "name": "errno",
+      "version": "0.3.14",
+      "package_url": "https://github.com/lambda-fairy/rust-errno",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/errno/0.3.14/download",
+          "sha256": "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "errno",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "errno",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [],
+          "selects": {
+            "cfg(target_os = \"hermit\")": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(target_os = \"wasi\")": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(unix)": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(windows)": [
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ]
+          }
+        },
+        "edition": "2018",
+        "version": "0.3.14"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "fastrand 2.5.0": {
+      "name": "fastrand",
+      "version": "2.5.0",
+      "package_url": "https://github.com/smol-rs/fastrand",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/fastrand/2.5.0/download",
+          "sha256": "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "fastrand",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "fastrand",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2018",
+        "version": "2.5.0"
+      },
+      "license": "Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "fuzztest 0.1.0": {
+      "name": "fuzztest",
+      "version": "0.1.0",
+      "package_url": null,
+      "repository": null,
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "fuzztest",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "fuzztest",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "anyhow 1.0.104",
+              "target": "anyhow"
+            },
+            {
+              "id": "clap 4.6.4",
+              "target": "clap"
+            },
+            {
+              "id": "humantime 2.4.0",
+              "target": "humantime"
+            },
+            {
+              "id": "inventory 0.3.24",
+              "target": "inventory"
+            },
+            {
+              "id": "num-traits 0.2.19",
+              "target": "num_traits"
+            },
+            {
+              "id": "postcard 1.1.3",
+              "target": "postcard"
+            },
+            {
+              "id": "rand 0.10.2",
+              "target": "rand"
+            },
+            {
+              "id": "serde 1.0.229",
+              "target": "serde"
+            },
+            {
+              "id": "spin 0.10.1",
+              "target": "spin"
+            },
+            {
+              "id": "tempfile 3.27.0",
+              "target": "tempfile"
+            }
+          ],
+          "selects": {}
+        },
+        "deps_dev": {
+          "common": [
+            {
+              "id": "googletest 0.14.3",
+              "target": "googletest"
+            },
+            {
+              "id": "trybuild 1.0.118",
+              "target": "trybuild"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "0.1.0"
+      },
+      "license": null,
+      "license_ids": [],
+      "license_file": null
+    },
+    "fuzztest-macro 0.1.0": {
+      "name": "fuzztest-macro",
+      "version": "0.1.0",
+      "package_url": null,
+      "repository": null,
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "fuzztest_macro",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "fuzztest_macro",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "convert_case 0.4.0",
+              "target": "convert_case"
+            },
+            {
+              "id": "proc-macro-crate 3.5.0",
+              "target": "proc_macro_crate"
+            },
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "syn 2.0.119",
+              "target": "syn"
+            }
+          ],
+          "selects": {}
+        },
+        "deps_dev": {
+          "common": [
+            {
+              "id": "googletest 0.14.3",
+              "target": "googletest"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "0.1.0"
+      },
+      "license": null,
+      "license_ids": [],
+      "license_file": null
+    },
+    "getrandom 0.4.3": {
+      "name": "getrandom",
+      "version": "0.4.3",
+      "package_url": "https://github.com/rust-random/getrandom",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/getrandom/0.4.3/download",
+          "sha256": "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "getrandom",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "getrandom",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "std",
+            "sys_rng"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "cfg-if 1.0.4",
+              "target": "cfg_if"
+            },
+            {
+              "id": "getrandom 0.4.3",
+              "target": "build_script_build"
+            },
+            {
+              "id": "rand_core 0.10.1",
+              "target": "rand_core"
+            }
+          ],
+          "selects": {
+            "cfg(all(any(target_os = \"linux\", target_os = \"android\"), not(any(all(target_os = \"linux\", target_env = \"\"), getrandom_backend = \"custom\", getrandom_backend = \"linux_raw\", getrandom_backend = \"rdrand\", getrandom_backend = \"rndr\"))))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(all(target_os = \"uefi\", getrandom_backend = \"efi_rng\"))": [
+              {
+                "id": "r-efi 6.0.0",
+                "target": "r_efi"
+              }
+            ],
+            "cfg(any(target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"hurd\", target_os = \"illumos\", target_os = \"cygwin\", all(target_os = \"horizon\", target_arch = \"arm\")))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(any(target_os = \"haiku\", target_os = \"redox\", target_os = \"nto\", target_os = \"aix\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(any(target_os = \"ios\", target_os = \"visionos\", target_os = \"watchos\", target_os = \"tvos\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(any(target_os = \"macos\", target_os = \"openbsd\", target_os = \"vita\", target_os = \"emscripten\"))": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(target_os = \"netbsd\")": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(target_os = \"solaris\")": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(target_os = \"vxworks\")": [
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ]
+          }
+        },
+        "edition": "2024",
+        "version": "0.4.3"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "glob 0.3.4": {
+      "name": "glob",
+      "version": "0.3.4",
+      "package_url": "https://github.com/rust-lang/glob",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/glob/0.3.4/download",
+          "sha256": "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "glob",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "glob",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "0.3.4"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "googletest 0.14.3": {
+      "name": "googletest",
+      "version": "0.14.3",
+      "package_url": "https://github.com/google/googletest-rust",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/googletest/0.14.3/download",
+          "sha256": "f6b5e2f2b556b7b90297a5a35c8267dd43a537923d2b329beefdba2b4ec19d94"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "googletest",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "googletest",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "num-traits 0.2.19",
+              "target": "num_traits"
+            },
+            {
+              "id": "regex 1.13.1",
+              "target": "regex"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "proc_macro_deps": {
+          "common": [
+            {
+              "id": "googletest_macro 0.14.3",
+              "target": "googletest_macro"
+            },
+            {
+              "id": "rustversion 1.0.23",
+              "target": "rustversion"
+            }
+          ],
+          "selects": {}
+        },
+        "version": "0.14.3"
+      },
+      "license": "Apache-2.0",
+      "license_ids": [
+        "Apache-2.0"
+      ],
+      "license_file": "LICENSE"
+    },
+    "googletest_macro 0.14.3": {
+      "name": "googletest_macro",
+      "version": "0.14.3",
+      "package_url": "https://github.com/google/googletest-rust",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/googletest_macro/0.14.3/download",
+          "sha256": "2ae6abc96141edd26bf5aeec0f119c129c44de3ced09e5073711a02cb74725d0"
+        }
+      },
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "googletest_macro",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "googletest_macro",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "syn 2.0.119",
+              "target": "syn"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.14.3"
+      },
+      "license": "Apache-2.0",
+      "license_ids": [
+        "Apache-2.0"
+      ],
+      "license_file": "LICENSE"
+    },
+    "hash32 0.2.1": {
+      "name": "hash32",
+      "version": "0.2.1",
+      "package_url": "https://github.com/japaric/hash32",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/hash32/0.2.1/download",
+          "sha256": "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "hash32",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "hash32",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "byteorder 1.5.0",
+              "target": "byteorder"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2015",
+        "version": "0.2.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "hashbrown 0.17.1": {
+      "name": "hashbrown",
+      "version": "0.17.1",
+      "package_url": "https://github.com/rust-lang/hashbrown",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/hashbrown/0.17.1/download",
+          "sha256": "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "hashbrown",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "hashbrown",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2024",
+        "version": "0.17.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "heapless 0.7.17": {
+      "name": "heapless",
+      "version": "0.7.17",
+      "package_url": "https://github.com/japaric/heapless",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/heapless/0.7.17/download",
+          "sha256": "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "heapless",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "heapless",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "atomic-polyfill",
+            "cas",
+            "serde"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "hash32 0.2.1",
+              "target": "hash32"
+            },
+            {
+              "id": "heapless 0.7.17",
+              "target": "build_script_build"
+            },
+            {
+              "id": "serde 1.0.229",
+              "target": "serde"
+            },
+            {
+              "id": "stable_deref_trait 1.2.1",
+              "target": "stable_deref_trait"
+            }
+          ],
+          "selects": {
+            "cfg(target_arch = \"x86_64\")": [
+              {
+                "id": "spin 0.9.9",
+                "target": "spin"
+              }
+            ],
+            "riscv32i-unknown-none-elf": [
+              {
+                "id": "atomic-polyfill 1.0.3",
+                "target": "atomic_polyfill"
+              }
+            ],
+            "riscv32imc-unknown-none-elf": [
+              {
+                "id": "atomic-polyfill 1.0.3",
+                "target": "atomic_polyfill"
+              }
+            ],
+            "xtensa-esp32s2-none-elf": [
+              {
+                "id": "atomic-polyfill 1.0.3",
+                "target": "atomic_polyfill"
+              }
+            ]
+          }
+        },
+        "edition": "2018",
+        "version": "0.7.17"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "rustc_version 0.4.1",
+              "target": "rustc_version"
+            }
+          ],
+          "selects": {}
+        }
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "heck 0.5.0": {
+      "name": "heck",
+      "version": "0.5.0",
+      "package_url": "https://github.com/withoutboats/heck",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/heck/0.5.0/download",
+          "sha256": "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "heck",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "heck",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "0.5.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "humantime 2.4.0": {
+      "name": "humantime",
+      "version": "2.4.0",
+      "package_url": "https://github.com/chronotope/humantime",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/humantime/2.4.0/download",
+          "sha256": "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "humantime",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "humantime",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "2.4.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "indexmap 2.14.0": {
+      "name": "indexmap",
+      "version": "2.14.0",
+      "package_url": "https://github.com/indexmap-rs/indexmap",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/indexmap/2.14.0/download",
+          "sha256": "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "indexmap",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "indexmap",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "equivalent 1.0.2",
+              "target": "equivalent"
+            },
+            {
+              "id": "hashbrown 0.17.1",
+              "target": "hashbrown"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "2.14.0"
+      },
+      "license": "Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "inventory 0.3.24": {
+      "name": "inventory",
+      "version": "0.3.24",
+      "package_url": "https://github.com/dtolnay/inventory",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/inventory/0.3.24/download",
+          "sha256": "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "inventory",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "inventory",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "proc_macro_deps": {
+          "common": [],
+          "selects": {
+            "cfg(target_family = \"wasm\")": [
+              {
+                "id": "rustversion 1.0.23",
+                "target": "rustversion"
+              }
+            ]
+          }
+        },
+        "version": "0.3.24"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "is_terminal_polyfill 1.70.2": {
+      "name": "is_terminal_polyfill",
+      "version": "1.70.2",
+      "package_url": "https://github.com/polyfill-rs/is_terminal_polyfill",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/is_terminal_polyfill/1.70.2/download",
+          "sha256": "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "is_terminal_polyfill",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "is_terminal_polyfill",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.70.2"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "itoa 1.0.18": {
+      "name": "itoa",
+      "version": "1.0.18",
+      "package_url": "https://github.com/dtolnay/itoa",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/itoa/1.0.18/download",
+          "sha256": "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "itoa",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "itoa",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "1.0.18"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "libc 0.2.189": {
+      "name": "libc",
+      "version": "0.2.189",
+      "package_url": "https://github.com/rust-lang/libc",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/libc/0.2.189/download",
+          "sha256": "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "libc",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "libc",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [],
+          "selects": {
+            "aarch64-apple-darwin": [
+              "std"
+            ],
+            "wasm32-wasip1": [
+              "std"
+            ]
+          }
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "libc 0.2.189",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.2.189"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "linux-raw-sys 0.12.1": {
+      "name": "linux-raw-sys",
+      "version": "0.12.1",
+      "package_url": "https://github.com/sunfishcode/linux-raw-sys",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/linux-raw-sys/0.12.1/download",
+          "sha256": "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "linux_raw_sys",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "linux_raw_sys",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "auxvec",
+            "elf",
+            "errno",
+            "general",
+            "ioctl",
+            "no_std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.12.1"
+      },
+      "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "lock_api 0.4.14": {
+      "name": "lock_api",
+      "version": "0.4.14",
+      "package_url": "https://github.com/Amanieu/parking_lot",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/lock_api/0.4.14/download",
+          "sha256": "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "lock_api",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "lock_api",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "atomic_usize",
+            "default"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "scopeguard 1.2.0",
+              "target": "scopeguard"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.4.14"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "memchr 2.8.3": {
+      "name": "memchr",
+      "version": "2.8.3",
+      "package_url": "https://github.com/BurntSushi/memchr",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/memchr/2.8.3/download",
+          "sha256": "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "memchr",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "memchr",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "2.8.3"
+      },
+      "license": "Unlicense OR MIT",
+      "license_ids": [
+        "MIT",
+        "Unlicense"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "num-traits 0.2.19": {
+      "name": "num-traits",
+      "version": "0.2.19",
+      "package_url": "https://github.com/rust-num/num-traits",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/num-traits/0.2.19/download",
+          "sha256": "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "num_traits",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "num_traits",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "num-traits 0.2.19",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.2.19"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "autocfg 1.5.1",
+              "target": "autocfg"
+            }
+          ],
+          "selects": {}
+        }
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "once_cell 1.21.4": {
+      "name": "once_cell",
+      "version": "1.21.4",
+      "package_url": "https://github.com/matklad/once_cell",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/once_cell/1.21.4/download",
+          "sha256": "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "once_cell",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "once_cell",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "race",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.21.4"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "once_cell_polyfill 1.70.2": {
+      "name": "once_cell_polyfill",
+      "version": "1.70.2",
+      "package_url": "https://github.com/polyfill-rs/once_cell_polyfill",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/once_cell_polyfill/1.70.2/download",
+          "sha256": "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "once_cell_polyfill",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "once_cell_polyfill",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.70.2"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "postcard 1.1.3": {
+      "name": "postcard",
+      "version": "1.1.3",
+      "package_url": "https://github.com/jamesmunns/postcard",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/postcard/1.1.3/download",
+          "sha256": "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "postcard",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "postcard",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "heapless",
+            "heapless-cas",
+            "use-std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "cobs 0.3.0",
+              "target": "cobs"
+            },
+            {
+              "id": "heapless 0.7.17",
+              "target": "heapless"
+            },
+            {
+              "id": "serde 1.0.229",
+              "target": "serde"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.1.3"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "proc-macro-crate 3.5.0": {
+      "name": "proc-macro-crate",
+      "version": "3.5.0",
+      "package_url": "https://github.com/bkchr/proc-macro-crate",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/proc-macro-crate/3.5.0/download",
+          "sha256": "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "proc_macro_crate",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "proc_macro_crate",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "toml_edit 0.25.13+spec-1.1.0",
+              "target": "toml_edit"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "3.5.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "proc-macro2 1.0.107": {
+      "name": "proc-macro2",
+      "version": "1.0.107",
+      "package_url": "https://github.com/dtolnay/proc-macro2",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/proc-macro2/1.0.107/download",
+          "sha256": "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "proc_macro2",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "proc_macro2",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "proc-macro"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "build_script_build"
+            },
+            {
+              "id": "unicode-ident 1.0.24",
+              "target": "unicode_ident"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.107"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "quote 1.0.47": {
+      "name": "quote",
+      "version": "1.0.47",
+      "package_url": "https://github.com/dtolnay/quote",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/quote/1.0.47/download",
+          "sha256": "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "quote",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "quote",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "proc-macro"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.47"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "r-efi 6.0.0": {
+      "name": "r-efi",
+      "version": "6.0.0",
+      "package_url": "https://github.com/r-efi/r-efi",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/r-efi/6.0.0/download",
+          "sha256": "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "r_efi",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "r_efi",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2018",
+        "version": "6.0.0"
+      },
+      "license": "MIT OR Apache-2.0 OR LGPL-2.1-or-later",
+      "license_ids": [
+        "Apache-2.0",
+        "LGPL-2.1",
+        "MIT"
+      ],
+      "license_file": null
+    },
+    "rand 0.10.2": {
+      "name": "rand",
+      "version": "0.10.2",
+      "package_url": "https://github.com/rust-random/rand",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/rand/0.10.2/download",
+          "sha256": "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "rand",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "rand",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "std",
+            "std_rng",
+            "sys_rng",
+            "thread_rng"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "chacha20 0.10.1",
+              "target": "chacha20"
+            },
+            {
+              "id": "getrandom 0.4.3",
+              "target": "getrandom"
+            },
+            {
+              "id": "rand_core 0.10.1",
+              "target": "rand_core"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "0.10.2"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "rand_core 0.10.1": {
+      "name": "rand_core",
+      "version": "0.10.1",
+      "package_url": "https://github.com/rust-random/rand_core",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/rand_core/0.10.1/download",
+          "sha256": "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "rand_core",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "rand_core",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2024",
+        "version": "0.10.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "regex 1.13.1": {
+      "name": "regex",
+      "version": "1.13.1",
+      "package_url": "https://github.com/rust-lang/regex",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/regex/1.13.1/download",
+          "sha256": "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "regex",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "regex",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "perf",
+            "perf-backtrack",
+            "perf-cache",
+            "perf-dfa",
+            "perf-inline",
+            "perf-literal",
+            "perf-onepass",
+            "std",
+            "unicode",
+            "unicode-age",
+            "unicode-bool",
+            "unicode-case",
+            "unicode-gencat",
+            "unicode-perl",
+            "unicode-script",
+            "unicode-segment"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "aho-corasick 1.1.4",
+              "target": "aho_corasick"
+            },
+            {
+              "id": "memchr 2.8.3",
+              "target": "memchr"
+            },
+            {
+              "id": "regex-automata 0.4.16",
+              "target": "regex_automata"
+            },
+            {
+              "id": "regex-syntax 0.8.11",
+              "target": "regex_syntax"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.13.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "regex-automata 0.4.16": {
+      "name": "regex-automata",
+      "version": "0.4.16",
+      "package_url": "https://github.com/rust-lang/regex",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/regex-automata/0.4.16/download",
+          "sha256": "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "regex_automata",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "regex_automata",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "dfa-onepass",
+            "hybrid",
+            "meta",
+            "nfa-backtrack",
+            "nfa-pikevm",
+            "nfa-thompson",
+            "perf-inline",
+            "perf-literal",
+            "perf-literal-multisubstring",
+            "perf-literal-substring",
+            "std",
+            "syntax",
+            "unicode",
+            "unicode-age",
+            "unicode-bool",
+            "unicode-case",
+            "unicode-gencat",
+            "unicode-perl",
+            "unicode-script",
+            "unicode-segment",
+            "unicode-word-boundary"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "aho-corasick 1.1.4",
+              "target": "aho_corasick"
+            },
+            {
+              "id": "memchr 2.8.3",
+              "target": "memchr"
+            },
+            {
+              "id": "regex-syntax 0.8.11",
+              "target": "regex_syntax"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.4.16"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "regex-syntax 0.8.11": {
+      "name": "regex-syntax",
+      "version": "0.8.11",
+      "package_url": "https://github.com/rust-lang/regex",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/regex-syntax/0.8.11/download",
+          "sha256": "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "regex_syntax",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "regex_syntax",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std",
+            "unicode",
+            "unicode-age",
+            "unicode-bool",
+            "unicode-case",
+            "unicode-gencat",
+            "unicode-perl",
+            "unicode-script",
+            "unicode-segment"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.8.11"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "rustc_version 0.4.1": {
+      "name": "rustc_version",
+      "version": "0.4.1",
+      "package_url": "https://github.com/djc/rustc-version-rs",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/rustc_version/0.4.1/download",
+          "sha256": "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "rustc_version",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "rustc_version",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "semver 1.0.28",
+              "target": "semver"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2018",
+        "version": "0.4.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "rustix 1.1.4": {
+      "name": "rustix",
+      "version": "1.1.4",
+      "package_url": "https://github.com/bytecodealliance/rustix",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/rustix/1.1.4/download",
+          "sha256": "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "rustix",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "rustix",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "fs",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "bitflags 2.13.1",
+              "target": "bitflags"
+            },
+            {
+              "id": "rustix 1.1.4",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {
+            "aarch64-apple-darwin": [
+              {
+                "id": "errno 0.3.14",
+                "target": "errno",
+                "alias": "libc_errno"
+              },
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(all(any(target_os = \"linux\", target_os = \"android\"), any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\")))))))": [
+              {
+                "id": "linux-raw-sys 0.12.1",
+                "target": "linux_raw_sys"
+              }
+            ],
+            "cfg(all(not(rustix_use_libc), not(miri), target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"))))": [
+              {
+                "id": "linux-raw-sys 0.12.1",
+                "target": "linux_raw_sys"
+              }
+            ],
+            "cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\")))))))": [
+              {
+                "id": "errno 0.3.14",
+                "target": "errno",
+                "alias": "libc_errno"
+              },
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ],
+            "cfg(windows)": [
+              {
+                "id": "errno 0.3.14",
+                "target": "errno",
+                "alias": "libc_errno"
+              },
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ],
+            "wasm32-wasip1": [
+              {
+                "id": "errno 0.3.14",
+                "target": "errno",
+                "alias": "libc_errno"
+              },
+              {
+                "id": "libc 0.2.189",
+                "target": "libc"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "1.1.4"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "rustversion 1.0.23": {
+      "name": "rustversion",
+      "version": "1.0.23",
+      "package_url": "https://github.com/dtolnay/rustversion",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/rustversion/1.0.23/download",
+          "sha256": "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
+        }
+      },
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "rustversion",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build/build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "rustversion",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "rustversion 1.0.23",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2018",
+        "version": "1.0.23"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "scopeguard 1.2.0": {
+      "name": "scopeguard",
+      "version": "1.2.0",
+      "package_url": "https://github.com/bluss/scopeguard",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/scopeguard/1.2.0/download",
+          "sha256": "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "scopeguard",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "scopeguard",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2015",
+        "version": "1.2.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "semver 1.0.28": {
+      "name": "semver",
+      "version": "1.0.28",
+      "package_url": "https://github.com/dtolnay/semver",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/semver/1.0.28/download",
+          "sha256": "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "semver",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "semver",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.28"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "serde 1.0.229": {
+      "name": "serde",
+      "version": "1.0.229",
+      "package_url": "https://github.com/serde-rs/serde",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/serde/1.0.229/download",
+          "sha256": "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "serde",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "serde",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "derive",
+            "serde_derive",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "serde 1.0.229",
+              "target": "build_script_build"
+            },
+            {
+              "id": "serde_core 1.0.229",
+              "target": "serde_core"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "proc_macro_deps": {
+          "common": [
+            {
+              "id": "serde_derive 1.0.229",
+              "target": "serde_derive"
+            }
+          ],
+          "selects": {}
+        },
+        "version": "1.0.229"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "serde_core 1.0.229": {
+      "name": "serde_core",
+      "version": "1.0.229",
+      "package_url": "https://github.com/serde-rs/serde",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/serde_core/1.0.229/download",
+          "sha256": "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "serde_core",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "serde_core",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "result",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "serde_core 1.0.229",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "proc_macro_deps": {
+          "common": [],
+          "selects": {
+            "cfg(any())": [
+              {
+                "id": "serde_derive 1.0.229",
+                "target": "serde_derive"
+              }
+            ]
+          }
+        },
+        "version": "1.0.229"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "serde_derive 1.0.229": {
+      "name": "serde_derive",
+      "version": "1.0.229",
+      "package_url": "https://github.com/serde-rs/serde",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/serde_derive/1.0.229/download",
+          "sha256": "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
+        }
+      },
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "serde_derive",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "serde_derive",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "syn 3.0.3",
+              "target": "syn"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.229"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "serde_json 1.0.151": {
+      "name": "serde_json",
+      "version": "1.0.151",
+      "package_url": "https://github.com/serde-rs/json",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/serde_json/1.0.151/download",
+          "sha256": "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "serde_json",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "serde_json",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "itoa 1.0.18",
+              "target": "itoa"
+            },
+            {
+              "id": "memchr 2.8.3",
+              "target": "memchr"
+            },
+            {
+              "id": "serde_core 1.0.229",
+              "target": "serde_core"
+            },
+            {
+              "id": "serde_json 1.0.151",
+              "target": "build_script_build"
+            },
+            {
+              "id": "zmij 1.0.23",
+              "target": "zmij"
+            }
+          ],
+          "selects": {
+            "cfg(any())": [
+              {
+                "id": "serde 1.0.229",
+                "target": "serde"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "1.0.151"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "serde_spanned 1.1.1": {
+      "name": "serde_spanned",
+      "version": "1.1.1",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/serde_spanned/1.1.1/download",
+          "sha256": "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "serde_spanned",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "serde_spanned",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "serde",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "serde_core 1.0.229",
+              "target": "serde_core"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "1.1.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "spin 0.9.9": {
+      "name": "spin",
+      "version": "0.9.9",
+      "package_url": "https://github.com/mvdnes/spin-rs.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/spin/0.9.9/download",
+          "sha256": "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "spin",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "spin",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "barrier",
+            "default",
+            "lazy",
+            "lock_api",
+            "lock_api_crate",
+            "mutex",
+            "once",
+            "rwlock",
+            "spin_mutex"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "lock_api 0.4.14",
+              "target": "lock_api",
+              "alias": "lock_api_crate"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2015",
+        "version": "0.9.9"
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": "LICENSE"
+    },
+    "spin 0.10.1": {
+      "name": "spin",
+      "version": "0.10.1",
+      "package_url": "https://github.com/mvdnes/spin-rs.git",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/spin/0.10.1/download",
+          "sha256": "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "spin",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "spin",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "barrier",
+            "default",
+            "lazy",
+            "lock_api",
+            "mutex",
+            "once",
+            "rwlock",
+            "spin_mutex"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "lock_api 0.4.14",
+              "target": "lock_api",
+              "alias": "lock_api_crate"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2015",
+        "version": "0.10.1"
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": "LICENSE"
+    },
+    "stable_deref_trait 1.2.1": {
+      "name": "stable_deref_trait",
+      "version": "1.2.1",
+      "package_url": "https://github.com/storyyeller/stable_deref_trait",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/stable_deref_trait/1.2.1/download",
+          "sha256": "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "stable_deref_trait",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "stable_deref_trait",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2015",
+        "version": "1.2.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "strsim 0.11.1": {
+      "name": "strsim",
+      "version": "0.11.1",
+      "package_url": "https://github.com/rapidfuzz/strsim-rs",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/strsim/0.11.1/download",
+          "sha256": "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "strsim",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "strsim",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2015",
+        "version": "0.11.1"
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": "LICENSE"
+    },
+    "syn 2.0.119": {
+      "name": "syn",
+      "version": "2.0.119",
+      "package_url": "https://github.com/dtolnay/syn",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/syn/2.0.119/download",
+          "sha256": "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "syn",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "syn",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "clone-impls",
+            "default",
+            "derive",
+            "extra-traits",
+            "full",
+            "parsing",
+            "printing",
+            "proc-macro",
+            "visit-mut"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "unicode-ident 1.0.24",
+              "target": "unicode_ident"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "2.0.119"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "syn 3.0.3": {
+      "name": "syn",
+      "version": "3.0.3",
+      "package_url": "https://github.com/dtolnay/syn",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/syn/3.0.3/download",
+          "sha256": "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "syn",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "syn",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "clone-impls",
+            "default",
+            "derive",
+            "full",
+            "parsing",
+            "printing",
+            "proc-macro"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "unicode-ident 1.0.24",
+              "target": "unicode_ident"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "3.0.3"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "target-triple 1.0.1": {
+      "name": "target-triple",
+      "version": "1.0.1",
+      "package_url": "https://github.com/dtolnay/target-triple",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/target-triple/1.0.1/download",
+          "sha256": "c3a6bfce3d99adfa72d24750a61f782f3036a81e7f86d8841ee1326deaebd171"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "target_triple",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "target_triple",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "target-triple 1.0.1",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.1"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "tempfile 3.27.0": {
+      "name": "tempfile",
+      "version": "3.27.0",
+      "package_url": "https://github.com/Stebalien/tempfile",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/tempfile/3.27.0/download",
+          "sha256": "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "tempfile",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "tempfile",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "getrandom"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "fastrand 2.5.0",
+              "target": "fastrand"
+            },
+            {
+              "id": "once_cell 1.21.4",
+              "target": "once_cell"
+            }
+          ],
+          "selects": {
+            "aarch64-apple-darwin": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ],
+            "aarch64-unknown-linux-gnu": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ],
+            "cfg(any(unix, target_os = \"wasi\"))": [
+              {
+                "id": "rustix 1.1.4",
+                "target": "rustix"
+              }
+            ],
+            "cfg(windows)": [
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ],
+            "wasm32-wasip1": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ],
+            "x86_64-pc-windows-msvc": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ],
+            "x86_64-unknown-linux-gnu": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ],
+            "x86_64-unknown-nixos-gnu": [
+              {
+                "id": "getrandom 0.4.3",
+                "target": "getrandom"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "3.27.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "termcolor 1.4.1": {
+      "name": "termcolor",
+      "version": "1.4.1",
+      "package_url": "https://github.com/BurntSushi/termcolor",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/termcolor/1.4.1/download",
+          "sha256": "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "termcolor",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "termcolor",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [],
+          "selects": {
+            "cfg(windows)": [
+              {
+                "id": "winapi-util 0.1.11",
+                "target": "winapi_util"
+              }
+            ]
+          }
+        },
+        "edition": "2018",
+        "version": "1.4.1"
+      },
+      "license": "Unlicense OR MIT",
+      "license_ids": [
+        "MIT",
+        "Unlicense"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "thiserror 2.0.19": {
+      "name": "thiserror",
+      "version": "2.0.19",
+      "package_url": "https://github.com/dtolnay/thiserror",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/thiserror/2.0.19/download",
+          "sha256": "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "thiserror",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "thiserror",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "thiserror 2.0.19",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "proc_macro_deps": {
+          "common": [
+            {
+              "id": "thiserror-impl 2.0.19",
+              "target": "thiserror_impl"
+            }
+          ],
+          "selects": {}
+        },
+        "version": "2.0.19"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "thiserror-impl 2.0.19": {
+      "name": "thiserror-impl",
+      "version": "2.0.19",
+      "package_url": "https://github.com/dtolnay/thiserror",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/thiserror-impl/2.0.19/download",
+          "sha256": "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
+        }
+      },
+      "targets": [
+        {
+          "ProcMacro": {
+            "crate_name": "thiserror_impl",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "thiserror_impl",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "proc-macro2 1.0.107",
+              "target": "proc_macro2"
+            },
+            {
+              "id": "quote 1.0.47",
+              "target": "quote"
+            },
+            {
+              "id": "syn 3.0.3",
+              "target": "syn"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "2.0.19"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "toml 1.1.3+spec-1.1.0": {
+      "name": "toml",
+      "version": "1.1.3+spec-1.1.0",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/toml/1.1.3+spec-1.1.0/download",
+          "sha256": "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "toml",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "toml",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default",
+            "display",
+            "parse",
+            "serde",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "serde_core 1.0.229",
+              "target": "serde_core"
+            },
+            {
+              "id": "serde_spanned 1.1.1",
+              "target": "serde_spanned"
+            },
+            {
+              "id": "toml_datetime 1.1.1+spec-1.1.0",
+              "target": "toml_datetime"
+            },
+            {
+              "id": "toml_parser 1.1.3+spec-1.1.0",
+              "target": "toml_parser"
+            },
+            {
+              "id": "toml_writer 1.1.2+spec-1.1.0",
+              "target": "toml_writer"
+            },
+            {
+              "id": "winnow 1.0.4",
+              "target": "winnow"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "1.1.3+spec-1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "toml_datetime 1.1.1+spec-1.1.0": {
+      "name": "toml_datetime",
+      "version": "1.1.1+spec-1.1.0",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/toml_datetime/1.1.1+spec-1.1.0/download",
+          "sha256": "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "toml_datetime",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "toml_datetime",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "serde",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "serde_core 1.0.229",
+              "target": "serde_core"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "1.1.1+spec-1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "toml_edit 0.25.13+spec-1.1.0": {
+      "name": "toml_edit",
+      "version": "0.25.13+spec-1.1.0",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/toml_edit/0.25.13+spec-1.1.0/download",
+          "sha256": "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "toml_edit",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "toml_edit",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "parse"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "indexmap 2.14.0",
+              "target": "indexmap"
+            },
+            {
+              "id": "toml_datetime 1.1.1+spec-1.1.0",
+              "target": "toml_datetime"
+            },
+            {
+              "id": "toml_parser 1.1.3+spec-1.1.0",
+              "target": "toml_parser"
+            },
+            {
+              "id": "winnow 1.0.4",
+              "target": "winnow"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "0.25.13+spec-1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "toml_parser 1.1.3+spec-1.1.0": {
+      "name": "toml_parser",
+      "version": "1.1.3+spec-1.1.0",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/toml_parser/1.1.3+spec-1.1.0/download",
+          "sha256": "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "toml_parser",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "toml_parser",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "default",
+            "std"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "winnow 1.0.4",
+              "target": "winnow"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "1.1.3+spec-1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "toml_writer 1.1.2+spec-1.1.0": {
+      "name": "toml_writer",
+      "version": "1.1.2+spec-1.1.0",
+      "package_url": "https://github.com/toml-rs/toml",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/toml_writer/1.1.2+spec-1.1.0/download",
+          "sha256": "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "toml_writer",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "toml_writer",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "version": "1.1.2+spec-1.1.0"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "trybuild 1.0.118": {
+      "name": "trybuild",
+      "version": "1.0.118",
+      "package_url": "https://github.com/dtolnay/trybuild",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/trybuild/1.0.118/download",
+          "sha256": "06649c6f63d86604ba0c8950d5a1829fc9a17afd70fc6629f481d75b6a624c78"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "trybuild",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "trybuild",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "diff"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "dissimilar 1.0.11",
+              "target": "dissimilar"
+            },
+            {
+              "id": "glob 0.3.4",
+              "target": "glob"
+            },
+            {
+              "id": "serde 1.0.229",
+              "target": "serde"
+            },
+            {
+              "id": "serde_json 1.0.151",
+              "target": "serde_json"
+            },
+            {
+              "id": "target-triple 1.0.1",
+              "target": "target_triple"
+            },
+            {
+              "id": "termcolor 1.4.1",
+              "target": "termcolor"
+            },
+            {
+              "id": "toml 1.1.3+spec-1.1.0",
+              "target": "toml"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2024",
+        "proc_macro_deps": {
+          "common": [
+            {
+              "id": "serde_derive 1.0.229",
+              "target": "serde_derive"
+            }
+          ],
+          "selects": {}
+        },
+        "version": "1.0.118"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "unicode-ident 1.0.24": {
+      "name": "unicode-ident",
+      "version": "1.0.24",
+      "package_url": "https://github.com/dtolnay/unicode-ident",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/unicode-ident/1.0.24/download",
+          "sha256": "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "unicode_ident",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "unicode_ident",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "1.0.24"
+      },
+      "license": "(MIT OR Apache-2.0) AND Unicode-3.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT",
+        "Unicode-3.0"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "utf8parse 0.2.2": {
+      "name": "utf8parse",
+      "version": "0.2.2",
+      "package_url": "https://github.com/alacritty/vte",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/utf8parse/0.2.2/download",
+          "sha256": "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "utf8parse",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "utf8parse",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "default"
+          ],
+          "selects": {}
+        },
+        "edition": "2018",
+        "version": "0.2.2"
+      },
+      "license": "Apache-2.0 OR MIT",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "LICENSE-APACHE"
+    },
+    "winapi-util 0.1.11": {
+      "name": "winapi-util",
+      "version": "0.1.11",
+      "package_url": "https://github.com/BurntSushi/winapi-util",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/winapi-util/0.1.11/download",
+          "sha256": "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "winapi_util",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "winapi_util",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [],
+          "selects": {
+            "cfg(windows)": [
+              {
+                "id": "windows-sys 0.61.2",
+                "target": "windows_sys"
+              }
+            ]
+          }
+        },
+        "edition": "2021",
+        "version": "0.1.11"
+      },
+      "license": "Unlicense OR MIT",
+      "license_ids": [
+        "MIT",
+        "Unlicense"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "windows-link 0.2.1": {
+      "name": "windows-link",
+      "version": "0.2.1",
+      "package_url": "https://github.com/microsoft/windows-rs",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/windows-link/0.2.1/download",
+          "sha256": "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "windows_link",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "windows_link",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "edition": "2021",
+        "version": "0.2.1"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "license-apache-2.0"
+    },
+    "windows-sys 0.61.2": {
+      "name": "windows-sys",
+      "version": "0.61.2",
+      "package_url": "https://github.com/microsoft/windows-rs",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/windows-sys/0.61.2/download",
+          "sha256": "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "windows_sys",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "windows_sys",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "Win32",
+            "Win32_Foundation",
+            "Win32_Storage",
+            "Win32_Storage_FileSystem",
+            "Win32_System",
+            "Win32_System_Console",
+            "Win32_System_SystemInformation",
+            "default"
+          ],
+          "selects": {}
+        },
+        "deps": {
+          "common": [
+            {
+              "id": "windows-link 0.2.1",
+              "target": "windows_link"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "0.61.2"
+      },
+      "license": "MIT OR Apache-2.0",
+      "license_ids": [
+        "Apache-2.0",
+        "MIT"
+      ],
+      "license_file": "license-apache-2.0"
+    },
+    "winnow 1.0.4": {
+      "name": "winnow",
+      "version": "1.0.4",
+      "package_url": "https://github.com/winnow-rs/winnow",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/winnow/1.0.4/download",
+          "sha256": "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "winnow",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "winnow",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "crate_features": {
+          "common": [
+            "alloc",
+            "ascii",
+            "binary",
+            "default",
+            "parser",
+            "std"
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.4"
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": "LICENSE-MIT"
+    },
+    "zmij 1.0.23": {
+      "name": "zmij",
+      "version": "1.0.23",
+      "package_url": "https://github.com/dtolnay/zmij",
+      "repository": {
+        "Http": {
+          "url": "https://static.crates.io/crates/zmij/1.0.23/download",
+          "sha256": "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
+        }
+      },
+      "targets": [
+        {
+          "Library": {
+            "crate_name": "zmij",
+            "crate_root": "src/lib.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        },
+        {
+          "BuildScript": {
+            "crate_name": "build_script_build",
+            "crate_root": "build.rs",
+            "srcs": {
+              "allow_empty": true,
+              "include": [
+                "**/*.rs"
+              ]
+            }
+          }
+        }
+      ],
+      "library_target_name": "zmij",
+      "common_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "deps": {
+          "common": [
+            {
+              "id": "zmij 1.0.23",
+              "target": "build_script_build"
+            }
+          ],
+          "selects": {}
+        },
+        "edition": "2021",
+        "version": "1.0.23"
+      },
+      "build_script_attrs": {
+        "compile_data_glob": [
+          "**"
+        ],
+        "compile_data_glob_excludes": [
+          "**/*.rs"
+        ],
+        "data_glob": [
+          "**"
+        ]
+      },
+      "license": "MIT",
+      "license_ids": [
+        "MIT"
+      ],
+      "license_file": "LICENSE-MIT"
+    }
+  },
+  "binary_crates": [],
+  "workspace_members": {
+    "coverage 0.1.0": "rust/coverage",
+    "engine-ffi 0.1.0": "rust/engine",
+    "fuzztest 0.1.0": "rust",
+    "fuzztest-macro 0.1.0": "rust/fuzztest_macro"
+  },
+  "conditions": {
+    "aarch64-apple-darwin": [
+      "aarch64-apple-darwin"
+    ],
+    "aarch64-unknown-linux-gnu": [
+      "aarch64-unknown-linux-gnu"
+    ],
+    "cfg(all(any(target_os = \"linux\", target_os = \"android\"), any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\")))))))": [],
+    "cfg(all(any(target_os = \"linux\", target_os = \"android\"), not(any(all(target_os = \"linux\", target_env = \"\"), getrandom_backend = \"custom\", getrandom_backend = \"linux_raw\", getrandom_backend = \"rdrand\", getrandom_backend = \"rndr\"))))": [
+      "aarch64-unknown-linux-gnu",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(all(not(rustix_use_libc), not(miri), target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\"))))": [
+      "aarch64-unknown-linux-gnu",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = \"linux\", any(target_endian = \"little\", any(target_arch = \"s390x\", target_arch = \"powerpc\")), any(target_arch = \"arm\", all(target_arch = \"aarch64\", target_pointer_width = \"64\"), target_arch = \"riscv64\", all(rustix_use_experimental_asm, target_arch = \"powerpc\"), all(rustix_use_experimental_asm, target_arch = \"powerpc64\"), all(rustix_use_experimental_asm, target_arch = \"s390x\"), all(rustix_use_experimental_asm, target_arch = \"mips\"), all(rustix_use_experimental_asm, target_arch = \"mips32r6\"), all(rustix_use_experimental_asm, target_arch = \"mips64\"), all(rustix_use_experimental_asm, target_arch = \"mips64r6\"), target_arch = \"x86\", all(target_arch = \"x86_64\", target_pointer_width = \"64\")))))))": [
+      "aarch64-apple-darwin",
+      "wasm32-unknown-unknown",
+      "wasm32-wasip1"
+    ],
+    "cfg(all(target_arch = \"aarch64\", target_os = \"android\"))": [],
+    "cfg(all(target_arch = \"aarch64\", target_os = \"linux\"))": [
+      "aarch64-unknown-linux-gnu"
+    ],
+    "cfg(all(target_arch = \"aarch64\", target_vendor = \"apple\"))": [
+      "aarch64-apple-darwin"
+    ],
+    "cfg(all(target_arch = \"loongarch64\", target_os = \"linux\"))": [],
+    "cfg(all(target_os = \"uefi\", getrandom_backend = \"efi_rng\"))": [],
+    "cfg(any())": [],
+    "cfg(any(target_arch = \"x86_64\", target_arch = \"x86\"))": [
+      "x86_64-pc-windows-msvc",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(any(target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"hurd\", target_os = \"illumos\", target_os = \"cygwin\", all(target_os = \"horizon\", target_arch = \"arm\")))": [],
+    "cfg(any(target_os = \"haiku\", target_os = \"redox\", target_os = \"nto\", target_os = \"aix\"))": [],
+    "cfg(any(target_os = \"ios\", target_os = \"visionos\", target_os = \"watchos\", target_os = \"tvos\"))": [],
+    "cfg(any(target_os = \"macos\", target_os = \"openbsd\", target_os = \"vita\", target_os = \"emscripten\"))": [
+      "aarch64-apple-darwin"
+    ],
+    "cfg(any(unix, target_os = \"wasi\"))": [
+      "aarch64-apple-darwin",
+      "aarch64-unknown-linux-gnu",
+      "wasm32-wasip1",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(target_arch = \"x86_64\")": [
+      "x86_64-pc-windows-msvc",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(target_family = \"wasm\")": [
+      "wasm32-unknown-unknown",
+      "wasm32-wasip1"
+    ],
+    "cfg(target_os = \"hermit\")": [],
+    "cfg(target_os = \"netbsd\")": [],
+    "cfg(target_os = \"solaris\")": [],
+    "cfg(target_os = \"vxworks\")": [],
+    "cfg(target_os = \"wasi\")": [
+      "wasm32-wasip1"
+    ],
+    "cfg(unix)": [
+      "aarch64-apple-darwin",
+      "aarch64-unknown-linux-gnu",
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "cfg(windows)": [
+      "x86_64-pc-windows-msvc"
+    ],
+    "riscv32i-unknown-none-elf": [],
+    "riscv32imc-unknown-none-elf": [],
+    "wasm32-unknown-unknown": [
+      "wasm32-unknown-unknown"
+    ],
+    "wasm32-wasip1": [
+      "wasm32-wasip1"
+    ],
+    "x86_64-pc-windows-msvc": [
+      "x86_64-pc-windows-msvc"
+    ],
+    "x86_64-unknown-linux-gnu": [
+      "x86_64-unknown-linux-gnu",
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "x86_64-unknown-nixos-gnu": [
+      "x86_64-unknown-nixos-gnu"
+    ],
+    "xtensa-esp32s2-none-elf": []
+  },
+  "direct_deps": [
+    "anyhow 1.0.104",
+    "clap 4.6.4",
+    "convert_case 0.4.0",
+    "humantime 2.4.0",
+    "inventory 0.3.24",
+    "num-traits 0.2.19",
+    "postcard 1.1.3",
+    "proc-macro-crate 3.5.0",
+    "proc-macro2 1.0.107",
+    "quote 1.0.47",
+    "rand 0.10.2",
+    "serde 1.0.229",
+    "spin 0.10.1",
+    "syn 2.0.119",
+    "tempfile 3.27.0"
+  ],
+  "direct_dev_deps": [
+    "googletest 0.14.3",
+    "trybuild 1.0.118"
+  ],
+  "unused_patches": []
+}
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..033c775
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,832 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anstream"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
+
+[[package]]
+name = "anstyle-parse"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
+
+[[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
+
+[[package]]
+name = "bitflags"
+version = "2.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+
+[[package]]
+name = "chacha20"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "rand_core",
+]
+
+[[package]]
+name = "clap"
+version = "4.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d91e0c145792ef73a6ad36d27c75ac09f1832222a3c209689d90f534685ee5b7"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f09628afdcc538b57f3c6341e9c8e9970f18e4a481690a64974d7023bd33548b"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d012d2b9d65aca7f18f4d9878a045bc17899bba951561ba5ec3c2ba1eed9a061"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 3.0.3",
+]
+
+[[package]]
+name = "clap_lex"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
+
+[[package]]
+name = "cobs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
+dependencies = [
+ "thiserror",
+]
+
+[[package]]
+name = "colorchoice"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
+
+[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
+name = "coverage"
+version = "0.1.0"
+
+[[package]]
+name = "cpufeatures"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
+name = "dissimilar"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e"
+
+[[package]]
+name = "embedded-io"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
+
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
+[[package]]
+name = "engine-ffi"
+version = "0.1.0"
+
+[[package]]
+name = "equivalent"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
+
+[[package]]
+name = "errno"
+version = "0.3.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
+
+[[package]]
+name = "fuzztest"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "clap",
+ "coverage",
+ "engine-ffi",
+ "fuzztest-macro",
+ "googletest",
+ "humantime",
+ "inventory",
+ "num-traits",
+ "postcard",
+ "rand",
+ "serde",
+ "spin 0.10.1",
+ "tempfile",
+ "trybuild",
+]
+
+[[package]]
+name = "fuzztest-macro"
+version = "0.1.0"
+dependencies = [
+ "convert_case",
+ "googletest",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "rand_core",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b"
+
+[[package]]
+name = "googletest"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6b5e2f2b556b7b90297a5a35c8267dd43a537923d2b329beefdba2b4ec19d94"
+dependencies = [
+ "googletest_macro",
+ "num-traits",
+ "regex",
+ "rustversion",
+]
+
+[[package]]
+name = "googletest_macro"
+version = "0.14.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ae6abc96141edd26bf5aeec0f119c129c44de3ced09e5073711a02cb74725d0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
+[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
+
+[[package]]
+name = "heapless"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "serde",
+ "spin 0.9.9",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
+[[package]]
+name = "humantime"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15"
+
+[[package]]
+name = "indexmap"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
+dependencies = [
+ "equivalent",
+ "hashbrown",
+]
+
+[[package]]
+name = "inventory"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
+
+[[package]]
+name = "itoa"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+
+[[package]]
+name = "libc"
+version = "0.2.189"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
+
+[[package]]
+name = "lock_api"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "memchr"
+version = "2.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
+
+[[package]]
+name = "once_cell_polyfill"
+version = "1.70.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
+
+[[package]]
+name = "postcard"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
+dependencies = [
+ "cobs",
+ "embedded-io 0.4.0",
+ "embedded-io 0.6.1",
+ "heapless",
+ "serde",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
+dependencies = [
+ "toml_edit",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "r-efi"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
+
+[[package]]
+name = "rand"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
+dependencies = [
+ "chacha20",
+ "getrandom",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69"
+
+[[package]]
+name = "regex"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rustix"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "semver"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
+
+[[package]]
+name = "serde"
+version = "1.0.229"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
+dependencies = [
+ "serde_core",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_core"
+version = "1.0.229"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.229"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 3.0.3",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.151"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
+dependencies = [
+ "itoa",
+ "memchr",
+ "serde",
+ "serde_core",
+ "zmij",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "spin"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spin"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "syn"
+version = "2.0.119"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "3.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "target-triple"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3a6bfce3d99adfa72d24750a61f782f3036a81e7f86d8841ee1326deaebd171"
+
+[[package]]
+name = "tempfile"
+version = "3.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
+dependencies = [
+ "fastrand",
+ "getrandom",
+ "once_cell",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "2.0.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 3.0.3",
+]
+
+[[package]]
+name = "toml"
+version = "1.1.3+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
+dependencies = [
+ "indexmap",
+ "serde_core",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_parser",
+ "toml_writer",
+ "winnow",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "1.1.1+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
+dependencies = [
+ "serde_core",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.25.13+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b"
+dependencies = [
+ "indexmap",
+ "toml_datetime",
+ "toml_parser",
+ "winnow",
+]
+
+[[package]]
+name = "toml_parser"
+version = "1.1.3+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
+dependencies = [
+ "winnow",
+]
+
+[[package]]
+name = "toml_writer"
+version = "1.1.2+spec-1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
+
+[[package]]
+name = "trybuild"
+version = "1.0.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06649c6f63d86604ba0c8950d5a1829fc9a17afd70fc6629f481d75b6a624c78"
+dependencies = [
+ "dissimilar",
+ "glob",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "target-triple",
+ "termcolor",
+ "toml",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "windows-link"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
+
+[[package]]
+name = "windows-sys"
+version = "0.61.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
+name = "winnow"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "zmij"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..9ea0da4
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,21 @@
+[workspace]
+members = ["rust", "rust/engine", "rust/fuzztest_macro"]
+resolver = "2"
+
+[workspace.dependencies]
+anyhow = "1.0.100"
+clap = { version = "4.6.1", features = ["derive", "env"] }
+convert_case = "0.4.0"
+googletest = "0.14.3"
+humantime = "2.4.0"
+inventory = "0.3.20"
+num-traits = "0.2"
+postcard = { version = "1.0.0", features = ["use-std"] }
+proc-macro-crate = "3.4.0"
+proc-macro2 = "1.0.106"
+quote = "1.0.45"
+rand = { version = "0.10.1", features = ["std_rng"] }
+serde = { version = "1.0", features = ["derive"] }
+spin = "0.10.0"
+syn = { version = "2.0.117", features = ["extra-traits", "full", "parsing", "printing", "visit-mut"] }
+tempfile = "3.27.0"
diff --git a/MODULE.bazel b/MODULE.bazel
index 4610482..0a0dc3e 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -28,6 +28,31 @@
     version = "0.6.1",
 )
 bazel_dep(
+    name = "rules_rust",
+    version = "0.71.3",
+)
+
+rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
+rust.toolchain(
+    edition = "2024",
+    versions = ["nightly/2026-07-01"],
+)
+use_repo(rust, "rust_toolchains")
+
+register_toolchains("@rust_toolchains//:all")
+
+crate = use_extension("@rules_rust//crate_universe:extensions.bzl", "crate")
+crate.from_cargo(
+    name = "crate_index",
+    cargo_lockfile = "//:Cargo.lock",
+    lockfile = "//:Cargo.Bazel.lock",
+    manifests = [
+        "//:Cargo.toml",
+    ],
+)
+use_repo(crate, "crate_index")
+
+bazel_dep(
     name = "abseil-cpp",
     version = "20260526.0",
 )
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
new file mode 100644
index 0000000..9454499
--- /dev/null
+++ b/MODULE.bazel.lock
@@ -0,0 +1,435 @@
+{
+  "lockFileVersion": 24,
+  "registryFileHashes": {
+    "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
+    "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
+    "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
+    "https://bcr.bazel.build/modules/abseil-cpp/20220623.1/MODULE.bazel": "73ae41b6818d423a11fd79d95aedef1258f304448193d4db4ff90e5e7a0f076c",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
+    "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.0/MODULE.bazel": "98dc378d64c12a4e4741ad3362f87fb737ee6a0886b2d90c3cdbb4d93ea3e0bf",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
+    "https://bcr.bazel.build/modules/abseil-cpp/20240722.0/MODULE.bazel": "88668a07647adbdc14cb3a7cd116fb23c9dda37a90a1681590b6c9d8339a5b84",
+    "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5",
+    "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
+    "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
+    "https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8",
+    "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2",
+    "https://bcr.bazel.build/modules/abseil-cpp/20260526.0/MODULE.bazel": "b4a76a8d70ba08aa0253fd5e374ca5a5fa6b15aba985a7bbe4467c138954830f",
+    "https://bcr.bazel.build/modules/abseil-cpp/20260526.0/source.json": "a39a26fec1b7037bdd7ea6c25cc098b99ae80af10ff0b6ec8c4bfe0df694f451",
+    "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a",
+    "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b",
+    "https://bcr.bazel.build/modules/antlr4-cpp-runtime/4.13.2/MODULE.bazel": "087a9f8cb3d9643938bacb3aa97d795492dae4b23ac4cbd3ed2cdcf66a2a38da",
+    "https://bcr.bazel.build/modules/antlr4-cpp-runtime/4.13.2/source.json": "524c7181de8478c1bb50d9ab135b1ba85b98986e7c1f362a41bf812bd1d8a421",
+    "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
+    "https://bcr.bazel.build/modules/apple_support/1.13.0/MODULE.bazel": "7c8cdea7e031b7f9f67f0b497adf6d2c6a2675e9304ca93a9af6ed84eef5a524",
+    "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
+    "https://bcr.bazel.build/modules/apple_support/1.17.1/MODULE.bazel": "655c922ab1209978a94ef6ca7d9d43e940cd97d9c172fb55f94d91ac53f8610b",
+    "https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458",
+    "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442",
+    "https://bcr.bazel.build/modules/apple_support/1.24.1/MODULE.bazel": "f46e8ddad60aef170ee92b2f3d00ef66c147ceafea68b6877cb45bd91737f5f8",
+    "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4",
+    "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d",
+    "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/MODULE.bazel": "004ba890363d05372a97248c37205ae64b6fa31047629cd2c0895a9d0c7779e8",
+    "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b",
+    "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/MODULE.bazel": "77dc393c43ad79398b05865444c5200c6f1aae6765615544f2c7730b5858d533",
+    "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.21.0/source.json": "062b1d3dba8adcfeb28fe60c185647f5a53ec0487ffe93cf0ae91566596e4b49",
+    "https://bcr.bazel.build/modules/aspect_rules_js/1.33.1/MODULE.bazel": "db3e7f16e471cf6827059d03af7c21859e7a0d2bc65429a3a11f005d46fc501b",
+    "https://bcr.bazel.build/modules/aspect_rules_js/1.39.0/MODULE.bazel": "aece421d479e3c31dc3e5f6d49a12acc2700457c03c556650ec7a0ff23fc0d95",
+    "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5",
+    "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/MODULE.bazel": "74bf20a7a6bd5f2be09607fdb4196cfd6f203422ea271752ec2b1afe95426101",
+    "https://bcr.bazel.build/modules/aspect_rules_js/2.3.8/source.json": "411ec9d79d6f5fe8a083359588c21d01a5b48d88a2cbd334a4c90365015b7836",
+    "https://bcr.bazel.build/modules/aspect_rules_lint/0.12.0/MODULE.bazel": "e767c5dbfeb254ec03275a7701b5cfde2c4d2873676804bc7cb27ddff3728fed",
+    "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/MODULE.bazel": "d0045b5eabb012be550a609589b3e5e47eba682344b19cfd9365d4d896ed07df",
+    "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.0/source.json": "5593e3f1cd0dd5147f7748e163307fd5c2e1077913d6945b58739ad8d770a290",
+    "https://bcr.bazel.build/modules/bazel_features/0.1.0/MODULE.bazel": "47011d645b0f949f42ee67f2e8775188a9cf4a0a1528aa2fa4952f2fd00906fd",
+    "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b",
+    "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
+    "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101",
+    "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
+    "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
+    "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
+    "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
+    "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
+    "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
+    "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a",
+    "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65",
+    "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
+    "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9",
+    "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
+    "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6",
+    "https://bcr.bazel.build/modules/bazel_features/1.36.0/MODULE.bazel": "596cb62090b039caf1cad1d52a8bc35cf188ca9a4e279a828005e7ee49a1bec3",
+    "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
+    "https://bcr.bazel.build/modules/bazel_features/1.43.0/MODULE.bazel": "defa2226f06ba20550d6548c3a2ea2a7929634437a52973869c20c225450eb91",
+    "https://bcr.bazel.build/modules/bazel_features/1.50.0/MODULE.bazel": "2083ef9c7a469f520890483ccf8e0189d6e71e2117e7752e15e6554433d5ae3e",
+    "https://bcr.bazel.build/modules/bazel_features/1.50.0/source.json": "e0ee3debde2789ff56e4452e612d126925ba9ab64d4bde79c67f099d2902df9b",
+    "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b",
+    "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
+    "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d",
+    "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.8.0/MODULE.bazel": "2fb3fb53675f6adfc1ca5bfbd5cfb655ae350fba4706d924a8ec7e3ba945671c",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/MODULE.bazel": "72997b29dfd95c3fa0d0c48322d05590418edef451f8db8db5509c57875fb4b7",
+    "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/source.json": "7ad77c1e8c1b84222d9b3f3cae016a76639435744c19330b0b37c0a3c9da7dc0",
+    "https://bcr.bazel.build/modules/boringssl/0.0.0-20211025-d4f1ab9/MODULE.bazel": "6ee6353f8b1a701fe2178e1d925034294971350b6d3ac37e67e5a7d463267834",
+    "https://bcr.bazel.build/modules/boringssl/0.0.0-20230215-5c22014/MODULE.bazel": "4b03dc0d04375fa0271174badcd202ed249870c8e895b26664fd7298abea7282",
+    "https://bcr.bazel.build/modules/boringssl/0.0.0-20240530-2db0eb3/MODULE.bazel": "d0405b762c5e87cd445b7015f2b8da5400ef9a8dbca0bfefa6c1cea79d528a97",
+    "https://bcr.bazel.build/modules/boringssl/0.20240913.0/MODULE.bazel": "fcaa7503a5213290831a91ed1eb538551cf11ac0bc3a6ad92d0fef92c5bd25fb",
+    "https://bcr.bazel.build/modules/boringssl/0.20241024.0/MODULE.bazel": "b540cff73d948cb79cb0bc108d7cef391d2098a25adabfda5043e4ef548dbc87",
+    "https://bcr.bazel.build/modules/boringssl/0.20241024.0/source.json": "d843092e682b84188c043ac742965d7f96e04c846c7e338187e03238674909a9",
+    "https://bcr.bazel.build/modules/brotli/1.1.0/MODULE.bazel": "3b5b90488995183419c4b5c9b063a164f6c0bc4d0d6b40550a612a5e860cc0fe",
+    "https://bcr.bazel.build/modules/brotli/1.1.0/source.json": "098a4fd315527166e8dfe1fd1537c96a737a83764be38fc43f4da231d600f3d0",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
+    "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
+    "https://bcr.bazel.build/modules/bzip2/1.0.8/MODULE.bazel": "83ee443b286b0b91566e5ee77e74ba6445895f3135467893871560f9e4ebc159",
+    "https://bcr.bazel.build/modules/bzip2/1.0.8/source.json": "b64f3a2f973749cf5f6ee32b3d804af56a35a746228a7845ed5daa31c8cc8af1",
+    "https://bcr.bazel.build/modules/c-ares/1.15.0/MODULE.bazel": "ba0a78360fdc83f02f437a9e7df0532ad1fbaa59b722f6e715c11effebaa0166",
+    "https://bcr.bazel.build/modules/c-ares/1.19.1.bcr.1/MODULE.bazel": "4894eaa219c932a8025c223e5dbf0826de226f8cb62bbed76466c9475598e22b",
+    "https://bcr.bazel.build/modules/c-ares/1.19.1.bcr.1/source.json": "fa4eb4f11c83cfdc2ea12ce9433f5a0a2c2686c60b2e469c146a05f495e9a4bd",
+    "https://bcr.bazel.build/modules/c-ares/1.19.1/MODULE.bazel": "73bca21720772370ff91cc8e88bbbaf14897720c6473e87c1ddc0f848284c313",
+    "https://bcr.bazel.build/modules/cel-spec/0.15.0/MODULE.bazel": "e1eed53d233acbdcf024b4b0bc1528116d92c29713251b5154078ab1348cb600",
+    "https://bcr.bazel.build/modules/cel-spec/0.15.0/source.json": "ab7dccdf21ea2261c0f809b5a5221a4d7f8b580309f285fdf1444baaca75d44a",
+    "https://bcr.bazel.build/modules/civetweb/1.16/MODULE.bazel": "46a38f9daeb57392e3827fce7d40926be0c802bd23cdd6bfd3a96c804de42fae",
+    "https://bcr.bazel.build/modules/civetweb/1.16/source.json": "ba8b9585adb8355cb51b999d57172fd05e7a762c56b8d4bac6db42c99de3beb7",
+    "https://bcr.bazel.build/modules/crc32c/1.1.0/MODULE.bazel": "f11439d063a2b4e0f19b56bb8da6a931f9691bf583bd1ec0718645bce6c62b06",
+    "https://bcr.bazel.build/modules/crc32c/1.1.0/source.json": "aabc6ce46d4b71343d500270c2ddfd45f59cff9fd171313bdd773bf620cf2a6f",
+    "https://bcr.bazel.build/modules/curl/8.4.0/MODULE.bazel": "0bc250aa1cb69590049383df7a9537c809591fcf876c620f5f097c58fdc9bc10",
+    "https://bcr.bazel.build/modules/curl/8.7.1/MODULE.bazel": "088221c35a2939c555e6e47cb31a81c15f8b59f4daa8009b1e9271a502d33485",
+    "https://bcr.bazel.build/modules/curl/8.8.0.bcr.3/MODULE.bazel": "df703a5a606a5bc264a95940113daa44197dc211f51230dd058323f2aa50efca",
+    "https://bcr.bazel.build/modules/curl/8.8.0.bcr.3/source.json": "ef03f6b660515bcfc9e284e8bdd3679895cc28afdaecd794a6059d47f22d1df1",
+    "https://bcr.bazel.build/modules/curl/8.8.0/MODULE.bazel": "7da3b3e79b0b4ee8f8c95d640bc6ad7b430ce66ef6e9c9d2bc29b3b5ef85f6fe",
+    "https://bcr.bazel.build/modules/cython/3.0.11-1/MODULE.bazel": "868b3f5c956c3657420d2302004c6bb92606bfa47e314bab7f2ba0630c7c966c",
+    "https://bcr.bazel.build/modules/cython/3.0.11-1/source.json": "da318be900b8ca9c3d1018839d3bebc5a8e1645620d0848fa2c696d4ecf7c296",
+    "https://bcr.bazel.build/modules/envoy_api/0.0.0-20241214-918efc9/MODULE.bazel": "24e05f6f52f37be63a795192848555a2c8c855e7814dbc1ed419fb04a7005464",
+    "https://bcr.bazel.build/modules/envoy_api/0.0.0-20250128-4de3c74/MODULE.bazel": "1fe72489212c530086e3ffb0e018b2bfef4663200ca03571570f9f006bef1d75",
+    "https://bcr.bazel.build/modules/envoy_api/0.0.0-20250128-4de3c74/source.json": "028519164a2e24563f4b43d810fdedc702daed90e71e7042d45ba82ad807b46f",
+    "https://bcr.bazel.build/modules/flatbuffers/25.12.19/MODULE.bazel": "fe3a7f7811f43264f68136ad99e64384d70b2a25245e09ab800c4bb83171da25",
+    "https://bcr.bazel.build/modules/flatbuffers/25.12.19/source.json": "ea0204be7a79de9141cee5fa436e58a14e88b39b5b59227b21efa0394474ebea",
+    "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8",
+    "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2",
+    "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996",
+    "https://bcr.bazel.build/modules/gazelle/0.30.0/MODULE.bazel": "f888a1effe338491f35f0e0e85003b47bb9d8295ccba73c37e07702d8d31c65b",
+    "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8",
+    "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350",
+    "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a",
+    "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0",
+    "https://bcr.bazel.build/modules/gazelle/0.37.0/MODULE.bazel": "d1327ba0907d0275ed5103bfbbb13518f6c04955b402213319d0d6c0ce9839d4",
+    "https://bcr.bazel.build/modules/gazelle/0.37.0/source.json": "b3adc10e2394e7f63ea88fb1d622d4894bfe9ec6961c493ae9a887723ab16831",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.4/MODULE.bazel": "c6d54a11dcf64ee63545f42561eda3fd94c1b5f5ebe1357011de63ae33739d5e",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.5/MODULE.bazel": "9ba9b31b984022828a950e3300410977eda2e35df35584c6b0b2d0c2e52766b7",
+    "https://bcr.bazel.build/modules/google_benchmark/1.8.5/source.json": "2c9c685f9b496f125b9e3a9c696c549d1ed2f33b75830a2fb6ac94fab23c0398",
+    "https://bcr.bazel.build/modules/google_cloud_cpp/3.0.0-rc1/MODULE.bazel": "d3dc3ee19f703239a67b5f954784706ffab28c0d5cf4dcc5253df8ee2feba8ff",
+    "https://bcr.bazel.build/modules/google_cloud_cpp/3.0.0-rc1/source.json": "0dfad712a3cd6843be34cd3b1b27d56741ce164a8e2ad633fa56932dab4b51b3",
+    "https://bcr.bazel.build/modules/googleapis-cc/1.0.0/MODULE.bazel": "cf01757e7590c56140a4b81638ff2b3e7074769e6271720bbf738fcda25b6fc2",
+    "https://bcr.bazel.build/modules/googleapis-cc/1.0.0/source.json": "ab0e3a2ee9968a8848f59872fbbfa3e1f768597d71d2229e6caa319d357967c7",
+    "https://bcr.bazel.build/modules/googleapis-grpc-cc/1.0.0/MODULE.bazel": "3553358a9d8d96026c9e28d9fb6c268574950d0be7fa9b4c0aeaf3c37c73f2d3",
+    "https://bcr.bazel.build/modules/googleapis-grpc-cc/1.0.0/source.json": "fa7b79043b3c82bf74f1f2fa45af289e19b247375868d0752db2c114a1c7366c",
+    "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/MODULE.bazel": "97c6a4d413b373d4cc97065da3de1b2166e22cbbb5f4cc9f05760bfa83619e24",
+    "https://bcr.bazel.build/modules/googleapis-rules-registry/1.0.0/source.json": "cf611c836a60e98e2e2ab2de8004f119e9f06878dcf4ea2d95a437b1b7a89fe9",
+    "https://bcr.bazel.build/modules/googleapis/0.0.0-20240326-1c8d509c5/MODULE.bazel": "a4b7e46393c1cdcc5a00e6f85524467c48c565256b22b5fae20f84ab4a999a68",
+    "https://bcr.bazel.build/modules/googleapis/0.0.0-20240819-fe8ba054a/MODULE.bazel": "117b7c7be7327ed5d6c482274533f2dbd78631313f607094d4625c28203cacdf",
+    "https://bcr.bazel.build/modules/googleapis/0.0.0-20250703-f9d6fe4a/MODULE.bazel": "d1a3f5d60acdc6466b2f86320855c8a5543cec1af1e4bf9d34d3115fe043c851",
+    "https://bcr.bazel.build/modules/googleapis/0.0.0-20250703-f9d6fe4a/source.json": "a51564703aa367b73e995ab01c8485860066ad39866065767871887c63122392",
+    "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
+    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
+    "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
+    "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108",
+    "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/MODULE.bazel": "827f54f492a3ce549c940106d73de332c2b30cebd0c20c0bc5d786aba7f116cb",
+    "https://bcr.bazel.build/modules/googletest/1.17.0.bcr.2/source.json": "3664514073a819992320ffbce5825e4238459df344d8b01748af2208f8d2e1eb",
+    "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46",
+    "https://bcr.bazel.build/modules/grpc-java/1.62.2/MODULE.bazel": "99b8771e8c7cacb130170fed2a10c9e8fed26334a93e73b42d2953250885a158",
+    "https://bcr.bazel.build/modules/grpc-java/1.66.0/MODULE.bazel": "86ff26209fac846adb89db11f3714b3dc0090fb2fb81575673cc74880cda4e7e",
+    "https://bcr.bazel.build/modules/grpc-java/1.69.0/MODULE.bazel": "53887af6a00b3b406d70175d3d07e84ea9362016ff55ea90b9185f0227bfaf98",
+    "https://bcr.bazel.build/modules/grpc-proto/0.0.0-20240627-ec30f58/MODULE.bazel": "88de79051e668a04726e9ea94a481ec6f1692086735fd6f488ab908b3b909238",
+    "https://bcr.bazel.build/modules/grpc/1.41.0/MODULE.bazel": "5bcbfc2b274dabea628f0649dc50c90cf36543b1cfc31624832538644ad1aae8",
+    "https://bcr.bazel.build/modules/grpc/1.56.3.bcr.1/MODULE.bazel": "cd5b1eb276b806ec5ab85032921f24acc51735a69ace781be586880af20ab33f",
+    "https://bcr.bazel.build/modules/grpc/1.62.1/MODULE.bazel": "2998211594b8a79a6b459c4e797cfa19f0fb8b3be3149760ec7b8c99abfd426f",
+    "https://bcr.bazel.build/modules/grpc/1.63.1.bcr.1/MODULE.bazel": "d7b9fef03bd175e6825237b521b18a3c29f1ac15f8aa52c8a1a0f3bd8f33d54b",
+    "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.2/MODULE.bazel": "0fa2b0fd028ce354febf0fe90f1ed8fecfbfc33118cddd95ac0418cc283333a0",
+    "https://bcr.bazel.build/modules/grpc/1.66.0.bcr.3/MODULE.bazel": "f6047e89faf488f5e3e65cb2594c6f5e86992abec7487163ff6b623526e543b0",
+    "https://bcr.bazel.build/modules/grpc/1.69.0/MODULE.bazel": "4e26e05c9e1ef291ccbc96aad8e457b1b8abedbc141623831629da2f8168eef6",
+    "https://bcr.bazel.build/modules/grpc/1.70.1/MODULE.bazel": "b800cd8e3e7555c1e61cba2e02d3a2fcf0e91f66e800db286d965d3b7a6a721a",
+    "https://bcr.bazel.build/modules/grpc/1.72.0/MODULE.bazel": "b2a82e2678717683f918ac87364005fd0bf3ae3bfca9b0cae68e918ba42594b1",
+    "https://bcr.bazel.build/modules/grpc/1.72.0/source.json": "214430b7958731283a23d0aeed8b5e1fd6a08132eb98fe77d5110f5142959335",
+    "https://bcr.bazel.build/modules/highwayhash/0.0.0-20240305-5ad3bf8/MODULE.bazel": "5c7f29d5bd70feff14b0f65b39584957e18e4a8d555e5a29a4c36019afbb44b9",
+    "https://bcr.bazel.build/modules/highwayhash/0.0.0-20240305-5ad3bf8/source.json": "211c0937ef5f537da6c3c135d12e60927c71b380642e207e4a02b86d29c55e85",
+    "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f",
+    "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5",
+    "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
+    "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0",
+    "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000",
+    "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
+    "https://bcr.bazel.build/modules/libpfm/4.11.0/source.json": "caaffb3ac2b59b8aac456917a4ecf3167d40478ee79f15ab7a877ec9273937c9",
+    "https://bcr.bazel.build/modules/lz4/1.9.4/MODULE.bazel": "e3d307b1d354d70f6c809167eafecf5d622c3f27e3971ab7273410f429c7f83a",
+    "https://bcr.bazel.build/modules/lz4/1.9.4/source.json": "233f0bdfc21f254e3dda14683ddc487ca68c6a3a83b7d5db904c503f85bd089b",
+    "https://bcr.bazel.build/modules/mbedtls/3.6.0/MODULE.bazel": "8e380e4698107c5f8766264d4df92e36766248447858db28187151d884995a09",
+    "https://bcr.bazel.build/modules/mbedtls/3.6.0/source.json": "1dbe7eb5258050afcc3806b9d43050f71c6f539ce0175535c670df606790b30c",
+    "https://bcr.bazel.build/modules/nlohmann_json/3.11.3/MODULE.bazel": "87023db2f55fc3a9949c7b08dc711fae4d4be339a80a99d04453c4bb3998eefc",
+    "https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.1/MODULE.bazel": "a1c8bb07b5b91d971727c635f449d05623ac9608f6fe4f5f04254ea12f08e349",
+    "https://bcr.bazel.build/modules/nlohmann_json/3.12.0.bcr.1/source.json": "93f82a5ae985eb935c539bfee95e04767187818189241ac956f3ccadbdb8fb02",
+    "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74",
+    "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/MODULE.bazel": "02201d2921dadb4ec90c4980eca4b2a02904eddcf6fa02f3da7594fb7b0d821c",
+    "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/source.json": "f50efc07822f5425bd1d3e40e977484f9c0142463052717d40ec85cd6744243e",
+    "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/MODULE.bazel": "4a2e8b4d0b544002502474d611a5a183aa282251e14f6a01afe841c0c1b10372",
+    "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/source.json": "a7d956700a85b833c43fc61455c0e111ab75bab40768ed17a206ee18a2bbe38f",
+    "https://bcr.bazel.build/modules/openssl/3.3.1.bcr.1/MODULE.bazel": "49c0c07e8fb87b480bccb842cfee1b32617f11dac590f732573c69058699a3d1",
+    "https://bcr.bazel.build/modules/openssl/3.3.1.bcr.1/source.json": "0c0872e048bbea052a9c541fb47019481a19201ba5555a71d762ad591bf94e1f",
+    "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "089a5613c2a159c7dfde098dabfc61e966889c7d6a81a98422a84c51535ed17d",
+    "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "b7379a140f538cea3f749179a2d481ed81942cc6f7b05a6113723eb34ac3b3e7",
+    "https://bcr.bazel.build/modules/opentelemetry-cpp/1.19.0/MODULE.bazel": "3455326c08b28415648a3d60d8e3c811847ebdbe64474f75b25878f25585aea1",
+    "https://bcr.bazel.build/modules/opentelemetry-cpp/1.19.0/source.json": "4e48137e4c3ecb99401ff99876df8fa330598d7da051869bec643446e8a8ff95",
+    "https://bcr.bazel.build/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "a49f406e99bf05ab43ed4f5b3322fbd33adfd484b6546948929d1316299b68bf",
+    "https://bcr.bazel.build/modules/opentelemetry-proto/1.3.1/MODULE.bazel": "0141a50e989576ee064c11ce8dd5ec89993525bd9f9a09c5618e4dacc8df9352",
+    "https://bcr.bazel.build/modules/opentelemetry-proto/1.4.0.bcr.1/MODULE.bazel": "5ceaf25e11170d22eded4c8032728b4a3f273765fccda32f9e94f463755c4167",
+    "https://bcr.bazel.build/modules/opentelemetry-proto/1.5.0/MODULE.bazel": "7543d91a53b98e7b5b37c5a0865b93bff12c1ee022b1e322cd236b968894b030",
+    "https://bcr.bazel.build/modules/opentelemetry-proto/1.5.0/source.json": "046b721ce203e88cdaad44d7dd17a86b7200eab9388b663b234e72e13ff7b143",
+    "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/MODULE.bazel": "b3925269f63561b8b880ae7cf62ccf81f6ece55b62cd791eda9925147ae116ec",
+    "https://bcr.bazel.build/modules/opentracing-cpp/1.6.0/source.json": "da1cb1add160f5e5074b7272e9db6fd8f1b3336c15032cd0a653af9d2f484aed",
+    "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92",
+    "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83",
+    "https://bcr.bazel.build/modules/package_metadata/0.0.3/source.json": "742075a428ad12a3fa18a69014c2f57f01af910c6d9d18646c990200853e641a",
+    "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
+    "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
+    "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
+    "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
+    "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
+    "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
+    "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
+    "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
+    "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580",
+    "https://bcr.bazel.build/modules/platforms/1.1.0/MODULE.bazel": "1c0c09f5bdcf4b3f924720d2478a3711cb39f4977019ca5988685e5b7e18b3d2",
+    "https://bcr.bazel.build/modules/platforms/1.1.0/source.json": "fcf351c47596c939140ab0d333dfdd08ed1ea6ce33c2fe70c12493a301cf1344",
+    "https://bcr.bazel.build/modules/prometheus-cpp/1.2.4/MODULE.bazel": "0fbe5dcff66311947a3f6b86ebc6a6d9328e31a28413ca864debc4a043f371e5",
+    "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0/MODULE.bazel": "ce82e086bbc0b60267e970f6a54b2ca6d0f22d3eb6633e00e2cc2899c700f3d8",
+    "https://bcr.bazel.build/modules/prometheus-cpp/1.3.0/source.json": "8cb66b4e535afc718e9d104a3db96ccb71a42ee816a100e50fd0d5ac843c0606",
+    "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
+    "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a",
+    "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12",
+    "https://bcr.bazel.build/modules/protobuf/26.0.bcr.1/MODULE.bazel": "8f04d38c2da40a3715ff6bdce4d32c5981e6432557571482d43a62c31a24c2cf",
+    "https://bcr.bazel.build/modules/protobuf/26.0.bcr.2/MODULE.bazel": "62e0b84ca727bdeb55a6fe1ef180e6b191bbe548a58305ea1426c158067be534",
+    "https://bcr.bazel.build/modules/protobuf/26.0/MODULE.bazel": "8402da964092af40097f4a205eec2a33fd4a7748dc43632b7d1629bfd9a2b856",
+    "https://bcr.bazel.build/modules/protobuf/27.0-rc2/MODULE.bazel": "b2b0dbafd57b6bec0ca9b251da02e628c357dab53a097570aa7d79d020f107cf",
+    "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
+    "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
+    "https://bcr.bazel.build/modules/protobuf/28.3/MODULE.bazel": "2b3764bbab2e46703412bd3b859efcf0322638ed015e88432df3bb740507a1e9",
+    "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
+    "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92",
+    "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
+    "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95",
+    "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
+    "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573",
+    "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
+    "https://bcr.bazel.build/modules/protobuf/30.0/MODULE.bazel": "0e736de5d52ad7824113f47e65256a26ee74b689ba859c5447a0663e5a075409",
+    "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e",
+    "https://bcr.bazel.build/modules/protobuf/33.5/MODULE.bazel": "df58cd1c41c9d1257afa7f3110b23d970c107bf806b2e4d8c59a344d05504b0c",
+    "https://bcr.bazel.build/modules/protobuf/33.5/source.json": "fe53cb512afd722159c4c763f3fbbcc6ab850d45d1f389d8374f91c11e83bcd7",
+    "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4.bcr.2/MODULE.bazel": "c4bd2c850211ff5b7dadf9d2d0496c1c922fdedc303c775b01dfd3b3efc907ed",
+    "https://bcr.bazel.build/modules/protoc-gen-validate/1.0.4/MODULE.bazel": "b8913c154b16177990f6126d2d2477d187f9ddc568e95ee3e2d50fc65d2c494a",
+    "https://bcr.bazel.build/modules/protoc-gen-validate/1.2.1.bcr.1/MODULE.bazel": "4bf09676b62fa587ae07e073420a76ec8766dcce7545e5f8c68cfa8e484b5120",
+    "https://bcr.bazel.build/modules/protoc-gen-validate/1.2.1.bcr.1/source.json": "c19071ebc4b53b5f1cfab9c66eefaf6e4179eb8a998970d07b1077687e777f29",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
+    "https://bcr.bazel.build/modules/pybind11_bazel/2.13.6/MODULE.bazel": "2d746fda559464b253b2b2e6073cb51643a2ac79009ca02100ebbc44b4548656",
+    "https://bcr.bazel.build/modules/pybind11_bazel/3.0.0/MODULE.bazel": "a2bfa6020ed603a00d944161c63173c7f109774e99bee0c2cd8dbf24159f8134",
+    "https://bcr.bazel.build/modules/pybind11_bazel/3.0.0/source.json": "d8f5104d4c21d272bf327ebe44366fb0b4c036cdaa1f5cceb21a408ca4ef2ef8",
+    "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/MODULE.bazel": "82fbcb2e42f9e0040e76ccc74c06c3e46dfd33c64ca359293f8b84df0e6dff4c",
+    "https://bcr.bazel.build/modules/rapidjson/1.1.0.bcr.20241007/source.json": "5c42389ad0e21fc06b95ad7c0b730008271624a2fa3292e0eab5f30e15adeee3",
+    "https://bcr.bazel.build/modules/re2/2021-09-01/MODULE.bazel": "bcb6b96f3b071e6fe2d8bed9cc8ada137a105f9d2c5912e91d27528b3d123833",
+    "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
+    "https://bcr.bazel.build/modules/re2/2024-05-01/MODULE.bazel": "55a3f059538f381107824e7d00df5df6d061ba1fb80e874e4909c0f0549e8f3e",
+    "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a",
+    "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
+    "https://bcr.bazel.build/modules/re2/2025-08-12.bcr.1/MODULE.bazel": "e09b434b122bfb786a69179f9b325e35cb1856c3f56a7a81dd61609260ed46e1",
+    "https://bcr.bazel.build/modules/re2/2025-11-05.bcr.1/MODULE.bazel": "3d9d4995833fc0334fc5c88b56a05288dd25d651544cd7b2233bbd6357bbeba0",
+    "https://bcr.bazel.build/modules/re2/2025-11-05.bcr.1/source.json": "7df1394aabda1c9bc188a302f5d54b1c657924edd04ebc57d2be29dbd7efd141",
+    "https://bcr.bazel.build/modules/riegeli/0.0.0-20250822-9f2744d/MODULE.bazel": "fe86a600f793402a4f5e838636a449b5cbf91289b3af5f3174f7d4fea9d4e784",
+    "https://bcr.bazel.build/modules/riegeli/0.0.0-20250822-9f2744d/source.json": "edc86dab694fb7c98b42145bc41a0e230107cc4f293e43149c35fd452d50daa7",
+    "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
+    "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
+    "https://bcr.bazel.build/modules/rules_apple/3.13.0/MODULE.bazel": "b4559a2c6281ca3165275bb36c1f0ac74666632adc5bdb680e366de7ce845f43",
+    "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a",
+    "https://bcr.bazel.build/modules/rules_apple/3.16.0/source.json": "d8b5fe461272018cc07cfafce11fe369c7525330804c37eec5a82f84cd475366",
+    "https://bcr.bazel.build/modules/rules_apple/3.5.1/MODULE.bazel": "3d1bbf65ad3692003d36d8a29eff54d4e5c1c5f4bfb60f79e28646a924d9101c",
+    "https://bcr.bazel.build/modules/rules_buf/0.1.1/MODULE.bazel": "6189aec18a4f7caff599ad41b851ab7645d4f1e114aa6431acf9b0666eb92162",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.5/MODULE.bazel": "be41f87587998fe8890cd82ea4e848ed8eb799e053c224f78f3ff7fe1a1d9b74",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
+    "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
+    "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
+    "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0",
+    "https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.18/MODULE.bazel": "4460ec36adc8f722a6a2a4ac9374cb91f2acebadaa93fc37966129afb3dece87",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.18/source.json": "abad668ff2fd63ada1ac49bf386d37e27048b89a3465a6fd968bb832b00a09d3",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.9/MODULE.bazel": "34263f1dca62ea664265438cef714d7db124c03e1ed55ebb4f1dc860164308d1",
+    "https://bcr.bazel.build/modules/rules_foreign_cc/0.15.1/MODULE.bazel": "c2c60d26c79fda484acb95cdbec46e89d6b28b4845cb277160ce1e0c8622bb88",
+    "https://bcr.bazel.build/modules/rules_foreign_cc/0.15.1/source.json": "a161811a63ba8a859086da3b7ff3ad04f2e9c255d7727b41087103fc0eb22f55",
+    "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
+    "https://bcr.bazel.build/modules/rules_go/0.33.0/MODULE.bazel": "a2b11b64cd24bf94f57454f53288a5dacfe6cb86453eee7761b7637728c1910c",
+    "https://bcr.bazel.build/modules/rules_go/0.38.1/MODULE.bazel": "fb8e73dd3b6fc4ff9d260ceacd830114891d49904f5bda1c16bc147bcc254f71",
+    "https://bcr.bazel.build/modules/rules_go/0.39.1/MODULE.bazel": "d34fb2a249403a5f4339c754f1e63dc9e5ad70b47c5e97faee1441fc6636cd61",
+    "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8",
+    "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270",
+    "https://bcr.bazel.build/modules/rules_go/0.45.1/MODULE.bazel": "6d7884f0edf890024eba8ab31a621faa98714df0ec9d512389519f0edff0281a",
+    "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd",
+    "https://bcr.bazel.build/modules/rules_go/0.48.0/MODULE.bazel": "d00ebcae0908ee3f5e6d53f68677a303d6d59a77beef879598700049c3980a03",
+    "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0",
+    "https://bcr.bazel.build/modules/rules_go/0.50.1/source.json": "205765fd30216c70321f84c9a967267684bdc74350af3f3c46c857d9f80a4fa2",
+    "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
+    "https://bcr.bazel.build/modules/rules_java/5.1.0/MODULE.bazel": "324b6478b0343a3ce7a9add8586ad75d24076d6d43d2f622990b9c1cfd8a1b15",
+    "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
+    "https://bcr.bazel.build/modules/rules_java/5.5.0/MODULE.bazel": "486ad1aa15cdc881af632b4b1448b0136c76025a1fe1ad1b65c5899376b83a50",
+    "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
+    "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963",
+    "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
+    "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
+    "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64",
+    "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
+    "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
+    "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
+    "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
+    "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934",
+    "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
+    "https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
+    "https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
+    "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
+    "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
+    "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2",
+    "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
+    "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.0/MODULE.bazel": "37c93a5a78d32e895d52f86a8d0416176e915daabd029ccb5594db422e87c495",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd",
+    "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
+    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
+    "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
+    "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
+    "https://bcr.bazel.build/modules/rules_license/0.0.8/MODULE.bazel": "5669c6fe49b5134dbf534db681ad3d67a2d49cfc197e4a95f1ca2fd7f3aebe96",
+    "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
+    "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
+    "https://bcr.bazel.build/modules/rules_nodejs/5.8.2/MODULE.bazel": "6bc03c8f37f69401b888023bf511cb6ee4781433b0cb56236b2e55a21e3a026a",
+    "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e",
+    "https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d",
+    "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/MODULE.bazel": "b66eadebd10f1f1b25f52f95ab5213a57e82c37c3f656fcd9a57ad04d2264ce7",
+    "https://bcr.bazel.build/modules/rules_nodejs/6.3.3/source.json": "45bd343155bdfed2543f0e39b80ff3f6840efc31975da4b5795797f4c94147ad",
+    "https://bcr.bazel.build/modules/rules_perl/0.2.4/MODULE.bazel": "5f5af7be4bf5fb88d91af7469518f0fd2161718aefc606188f7cd51f436ca938",
+    "https://bcr.bazel.build/modules/rules_perl/0.2.4/source.json": "574317d6b3c7e4843fe611b76f15e62a1889949f5570702e1ee4ad335ea3c339",
+    "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
+    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
+    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
+    "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
+    "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f",
+    "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
+    "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
+    "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96",
+    "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e",
+    "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
+    "https://bcr.bazel.build/modules/rules_python/0.22.0/MODULE.bazel": "b8057bafa11a9e0f4b08fc3b7cd7bee0dcbccea209ac6fc9a3ff051cd03e19e9",
+    "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
+    "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
+    "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
+    "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
+    "https://bcr.bazel.build/modules/rules_python/0.29.0/MODULE.bazel": "2ac8cd70524b4b9ec49a0b8284c79e4cd86199296f82f6e0d5da3f783d660c82",
+    "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
+    "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
+    "https://bcr.bazel.build/modules/rules_python/0.34.0/MODULE.bazel": "1d623d026e075b78c9fde483a889cda7996f5da4f36dffb24c246ab30f06513a",
+    "https://bcr.bazel.build/modules/rules_python/0.36.0/MODULE.bazel": "a4ce1ccea92b9106c7d16ab9ee51c6183107e78ba4a37aa65055227b80cd480c",
+    "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500",
+    "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
+    "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
+    "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43",
+    "https://bcr.bazel.build/modules/rules_python/1.2.0/MODULE.bazel": "5aeeb48b2a6c19d668b48adf2b8a2b209a6310c230db0ce77450f148a89846e4",
+    "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6",
+    "https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5",
+    "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8",
+    "https://bcr.bazel.build/modules/rules_python/1.6.3/MODULE.bazel": "a7b80c42cb3de5ee2a5fa1abc119684593704fcd2fec83165ebe615dec76574f",
+    "https://bcr.bazel.build/modules/rules_python/1.6.3/source.json": "f0be74977e5604a6526c8a416cda22985093ff7d5d380d41722d7e44015cc419",
+    "https://bcr.bazel.build/modules/rules_rust/0.45.1/MODULE.bazel": "a69d0db3a958fab2c6520961e1b2287afcc8b36690fd31bbc4f6f7391397150d",
+    "https://bcr.bazel.build/modules/rules_rust/0.51.0/MODULE.bazel": "2b6d1617ac8503bfdcc0e4520c20539d4bba3a691100bee01afe193ceb0310f9",
+    "https://bcr.bazel.build/modules/rules_rust/0.71.3/MODULE.bazel": "e2390c96f77d65f00c769bf665678c5424188e9c777239cfaae2a8d2dde7b981",
+    "https://bcr.bazel.build/modules/rules_rust/0.71.3/source.json": "5eb5d8068571725bc893045f8137ed7937988f23d73c53ea443470e8047598ad",
+    "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
+    "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b",
+    "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592",
+    "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b",
+    "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c",
+    "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca",
+    "https://bcr.bazel.build/modules/rules_swift/1.18.0/MODULE.bazel": "a6aba73625d0dc64c7b4a1e831549b6e375fbddb9d2dde9d80c9de6ec45b24c9",
+    "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046",
+    "https://bcr.bazel.build/modules/rules_swift/2.1.1/source.json": "40fc69dfaac64deddbb75bd99cdac55f4427d9ca0afbe408576a65428427a186",
+    "https://bcr.bazel.build/modules/snappy/1.2.0/MODULE.bazel": "cc7a727b46089c7fdae0ede21b1fd65bdb14d01823da118ef5c48044f40b6b27",
+    "https://bcr.bazel.build/modules/snappy/1.2.0/source.json": "17f5527e15d30a9d9eebf79ed73b280b56cac44f8c8fea696666d99943f84c33",
+    "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
+    "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
+    "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
+    "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd",
+    "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
+    "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
+    "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5",
+    "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216",
+    "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91",
+    "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/source.json": "32bd87e5f4d7acc57c5b2ff7c325ae3061d5e242c0c4c214ae87e0f1c13e54cb",
+    "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351",
+    "https://bcr.bazel.build/modules/tar.bzl/0.5.1/source.json": "deed3094f7cc779ed1d37a68403847b0e38d9dd9d931e03cb90825f3368b515f",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20211020-160625a/MODULE.bazel": "6cced416be2dc5b9c05efd5b997049ba795e5e4e6fafbe1624f4587767638928",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9",
+    "https://bcr.bazel.build/modules/upb/0.0.0-20230907-e7430e6/MODULE.bazel": "3a7dedadf70346e678dc059dbe44d05cbf3ab17f1ce43a1c7a42edc7cbf93fd9",
+    "https://bcr.bazel.build/modules/xds/0.0.0-20240423-555b57e/MODULE.bazel": "cea509976a77e34131411684ef05a1d6ad194dd71a8d5816643bc5b0af16dc0f",
+    "https://bcr.bazel.build/modules/xds/0.0.0-20240423-555b57e/source.json": "7227e1fcad55f3f3cab1a08691ecd753cb29cc6380a47bc650851be9f9ad6d20",
+    "https://bcr.bazel.build/modules/xz/5.4.5.bcr.1/MODULE.bazel": "c037f75fa1b7e1ff15fbd15d807a8ce545e9b02f02df0a9777aa9aa7d8b268bb",
+    "https://bcr.bazel.build/modules/xz/5.4.5.bcr.1/source.json": "766f28499a16fa9ed8dc94382d50e80ceda0d0ab80b79b7b104a67074ab10e1f",
+    "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072",
+    "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3",
+    "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
+    "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
+    "https://bcr.bazel.build/modules/zlib/1.2.13/MODULE.bazel": "aa6deb1b83c18ffecd940c4119aff9567cd0a671d7bba756741cb2ef043a29d5",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.1/MODULE.bazel": "6a9fe6e3fc865715a7be9823ce694ceb01e364c35f7a846bf0d2b34762bc066b",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.6/MODULE.bazel": "e937cf0a3772f93ad91f3c7af4f330b76a878bbfee06527ca1a9673b790eb896",
+    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.6/source.json": "5f397158198f338129c865a4c3ae21bc5626a9664b3c3b40fa3b3c2ec1ff83bf",
+    "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198",
+    "https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72",
+    "https://bcr.bazel.build/modules/zstd/1.5.6/MODULE.bazel": "471ebe7d3cdd8c6469390fcf623eb4779ff55fbee0a87f1dc57a1def468b96d4",
+    "https://bcr.bazel.build/modules/zstd/1.5.6/source.json": "02010c3333fc89b44fe861db049968decb6e688411f7f9d4f6791d74f9adfb51"
+  },
+  "selectedYankedVersions": {},
+  "moduleExtensions": {},
+  "facts": {}
+}
diff --git a/centipede/BUILD b/centipede/BUILD
index 3ad6fae..1259192 100644
--- a/centipede/BUILD
+++ b/centipede/BUILD
@@ -1003,8 +1003,6 @@
     name = "engine_worker",
     srcs = [
         "engine_worker.cc",
-        "runner_utils.cc",
-        "runner_utils.h",
     ],
     hdrs = ["engine_worker_abi.h"],
     deps = [
@@ -1013,6 +1011,7 @@
         ":feature",
         ":runner_request",
         ":runner_result",
+        ":runner_utils",
         ":shared_memory_blob_sequence",
         "@abseil-cpp//absl/base:nullability",
         "@com_google_fuzztest//common:defs",
@@ -1240,8 +1239,6 @@
         "reverse_pc_table.h",
         "runner_dl_info.cc",
         "runner_dl_info.h",
-        "runner_utils.cc",
-        "runner_utils.h",
         "sancov_callbacks.cc",
         "sancov_interceptors.cc",
         "sancov_object_array.cc",
@@ -1263,6 +1260,7 @@
         ":foreach_nonzero",
         ":int_utils",
         ":runner_cmp_trace",
+        ":runner_utils",
         "@abseil-cpp//absl/base:core_headers",
         "@abseil-cpp//absl/base:nullability",
         "@abseil-cpp//absl/numeric:bits",
@@ -2026,3 +2024,23 @@
         ":test_util_sh",
     ],
 )
+
+cc_library(
+    name = "runner_utils",
+    srcs = ["runner_utils.cc"],
+    hdrs = ["runner_utils.h"],
+    copts = DISABLE_SANCOV_COPTS,
+    deps = [
+        "@abseil-cpp//absl/base:nullability",
+    ],
+)
+
+cc_static_library(
+    name = "centipede_engine_static",
+    deps = [
+        ":engine_controller_with_subprocess",
+        ":engine_worker",
+        ":sancov_runtime",
+        ":weak_sancov_stubs",
+    ],
+)
diff --git a/rust/.rustfmt.toml b/rust/.rustfmt.toml
new file mode 100644
index 0000000..33b356d
--- /dev/null
+++ b/rust/.rustfmt.toml
@@ -0,0 +1,3 @@
+use_field_init_shorthand = true
+use_try_shorthand = true
+edition = "2021"
diff --git a/rust/BUILD b/rust/BUILD
new file mode 100644
index 0000000..d8e3a13
--- /dev/null
+++ b/rust/BUILD
@@ -0,0 +1,44 @@
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+
+licenses(["notice"])
+
+exports_files(["BUILD"])
+
+rust_library(
+    name = "fuzztest",
+    srcs = glob([
+        "src/**/*.rs",
+    ]),
+    edition = "2024",
+    proc_macro_deps = [
+        "@com_google_fuzztest//rust/fuzztest_macro:fuzztest_macro",
+    ],
+    rustc_flags = ["-Zallow-features=cfg_sanitize"],
+    visibility = ["__subpackages__"],
+    deps = [
+        "@crate_index//:anyhow",  # v1
+        "@crate_index//:clap",  # v4
+        "@crate_index//:humantime",  # v2
+        "@crate_index//:inventory",  # v0_3
+        "@crate_index//:num-traits",
+        "@crate_index//:postcard",  # v1
+        "@crate_index//:rand",  # v0_10
+        "@crate_index//:serde",  # v1
+        "@crate_index//:spin",  # v0_10
+        "@crate_index//:tempfile",  # v3
+        "@com_google_fuzztest//rust/coverage",
+        "@com_google_fuzztest//rust/engine",
+    ],
+)
+
+rust_test(
+    name = "fuzztest_test",
+    # Avoid interference when setting/resetting environment variables in tests.
+    args = ["--test-threads=1"],
+    crate = ":fuzztest",
+    edition = "2024",
+    rustc_flags = ["-Zallow-features=cfg_sanitize"],
+    deps = [
+        "@crate_index//:googletest",
+    ],
+)
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
new file mode 100644
index 0000000..31ce402
--- /dev/null
+++ b/rust/Cargo.toml
@@ -0,0 +1,37 @@
+[package]
+name = "fuzztest"
+version = "0.1.0"
+edition = "2024"
+
+[[test]]
+name = "trybuild"
+path = "tests/trybuild.rs"
+
+[dependencies]
+anyhow.workspace = true
+clap.workspace = true
+coverage = { path = "coverage" }
+engine = { path = "engine", package = "engine-ffi" }
+fuzztest-macro = { path = "fuzztest_macro" }
+humantime.workspace = true
+inventory.workspace = true
+num-traits.workspace = true
+postcard.workspace = true
+rand.workspace = true
+serde.workspace = true
+spin.workspace = true
+tempfile.workspace = true
+
+[dev-dependencies]
+googletest = "0.14.3"
+
+[dev-dependencies.trybuild]
+version = "1.0.103"
+features = ["diff"]
+
+[profile.fuzztest]
+inherits = 'release'
+panic = 'abort'
+opt-level = "s"
+debug = true
+split-debuginfo = "packed"
diff --git a/rust/README.md b/rust/README.md
new file mode 100644
index 0000000..deb8c06
--- /dev/null
+++ b/rust/README.md
@@ -0,0 +1,69 @@
+# FuzzTest Rust
+
+A framework for fuzzing Rust projects using FuzzTest.
+
+## Prerequisites
+
+1.  Clone the repository.
+2.  Build the C++ Centipede static library engine using Bazel (from the
+    repository root):
+
+    ```bash
+    cd /path/to/fuzztest
+    bazel build //centipede:centipede_engine_static
+    ```
+
+3.  Copy the libcentipede_engine_static.a library to another location:
+
+    ```bash
+    mkdir -p $HOME/.local/lib
+    cp /path/to/fuzztest/bazel-bin/centipede/libcentipede_engine_static.a \
+        $HOME/.local/lib/
+    ```
+
+## Setup a Project
+
+1.  Create a new Rust project:
+
+    ```bash
+    cargo new my_fuzz_project --bin
+    ```
+
+2.  Add `fuzztest` as a dependency in your `Cargo.toml`:
+
+    ```toml
+    [dependencies]
+    fuzztest = { path = "/path/to/fuzztest/rust" }
+    googletest = "0.14.3"
+    ```
+
+## Write a Fuzz Test
+
+In `src/main.rs`:
+
+```rust
+#[cfg(test)]
+mod tests {
+    use fuzztest::domains::arbitrary::Arbitrary;
+    use fuzztest::fuzztest;
+
+    #[fuzztest(a = Arbitrary::<i32>::default(), b = Arbitrary::<i32>::default())]
+    fn test_addition(a: i32, b: i32) {
+        let _ = a.wrapping_add(b);
+    }
+}
+```
+
+## Build and Run Fuzz Tests
+
+To run the fuzz tests, you must specify the path that contains the previously
+built `libcentipede_engine_static.a` using the `FUZZTEST_LIB_PATH` environment
+variable:
+
+```bash
+# Run all fuzztests in smoke-test mode.
+FUZZTEST_LIB_PATH="$HOME/.local/lib" cargo test __fuzztest_mod__
+```
+
+// TODO(the-shank): add example of more commands for fuzzing, alongwith sample
+outputs.
diff --git a/rust/coverage/BUILD b/rust/coverage/BUILD
new file mode 100644
index 0000000..4cf89ce
--- /dev/null
+++ b/rust/coverage/BUILD
@@ -0,0 +1,36 @@
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+
+licenses(["notice"])
+
+rust_library(
+    name = "coverage",
+    srcs = [
+        "src/coverage.rs",
+        "src/lib.rs",
+    ],
+    deps = [
+        "@com_google_fuzztest//centipede:sancov_runtime",
+    ],
+    edition = "2024",
+    visibility = ["@com_google_fuzztest//rust:__subpackages__"],
+)
+
+rust_test(
+    name = "coverage_test",
+    # Avoid interference on coverage collection between threads.
+    args = ["--test-threads=1"],
+    crate = ":coverage",
+    edition = "2024",
+    env = {
+        "CENTIPEDE_RUNNER_FLAGS": ":use_cmp_features:",
+    },
+    # TODO: b/437896409 - Replace with global config once it's available.
+    rustc_flags = [
+        "-Cpasses=sancov-module",
+        "-Cllvm-args=-sanitizer-coverage-level=1",
+        "-Cllvm-args=-sanitizer-coverage-trace-compares",
+    ],
+    deps = [
+        "@crate_index//:googletest",
+    ],
+)
diff --git a/rust/coverage/Cargo.toml b/rust/coverage/Cargo.toml
new file mode 100644
index 0000000..550a6c2
--- /dev/null
+++ b/rust/coverage/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "coverage"
+version = "0.1.0"
+edition = "2024"
+
+[lib]
+test = false
+
+[dependencies]
diff --git a/rust/coverage/src/coverage.rs b/rust/coverage/src/coverage.rs
new file mode 100644
index 0000000..258987e
--- /dev/null
+++ b/rust/coverage/src/coverage.rs
@@ -0,0 +1,78 @@
+use std::slice;
+
+#[repr(C)]
+pub struct SanCovRuntimeRawFeatureParts {
+    // Safety invariant: The only way to receive this type is through `SanCovRuntimeGetCoverage()`
+    // which guarantees that `ptr` always points to a valid slice of `size` elements.
+    ptr: *const u64,
+    size: usize,
+}
+
+impl SanCovRuntimeRawFeatureParts {
+    /// # Safety
+    ///
+    /// Must not be held on when its data has to be mutated. For example, do not hold on to it
+    /// when calling `SanCovRuntimeGetCoverage()`.
+    pub unsafe fn as_slice(&self) -> &[u64] {
+        // Safety: self ensures that `ptr` always points to a valid slice of `size` elements.
+        unsafe { slice::from_raw_parts(self.ptr, self.size) }
+    }
+}
+
+unsafe extern "C" {
+    pub safe fn SanCovRuntimeClearCoverage(full_clear: bool);
+
+    pub safe fn SanCovRuntimeGetCoverage(reject_input: bool) -> SanCovRuntimeRawFeatureParts;
+
+    pub safe fn SanCovRuntimePostProcessCoverage(reject_input: bool);
+
+    // Exposed only for testing purposes.
+    pub safe fn __sanitizer_cov_trace_const_cmp1(Arg1: u8, Arg2: u8);
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use googletest::prelude::*;
+
+    #[gtest]
+    fn should_collect_features_from_sancov_callback() {
+        SanCovRuntimeClearCoverage(true);
+
+        __sanitizer_cov_trace_const_cmp1(1, 1);
+
+        let features = SanCovRuntimeGetCoverage(false);
+        expect_false!(features.ptr.is_null());
+        expect_gt!(features.size, 0);
+    }
+
+    #[gtest]
+    fn should_not_collect_features_from_empty_user_code() {
+        SanCovRuntimeClearCoverage(true);
+
+        // An execution where sancov hooks such as
+        // `__sanitizer_cov_trace_const_cmp1` are not called.
+
+        let features = SanCovRuntimeGetCoverage(false);
+        expect_false!(features.ptr.is_null());
+        expect_eq!(features.size, 0);
+    }
+
+    #[gtest]
+    fn should_collect_features_from_user_code() {
+        let x = std::env::args().count();
+
+        SanCovRuntimeClearCoverage(true);
+
+        {
+            // An LLVM trace cmp callback is expected to be instrumented here.
+            if x == 2 {
+                std::hint::black_box(2); // To prevent dead code elimination.
+            }
+        }
+
+        let features = SanCovRuntimeGetCoverage(false);
+        expect_false!(features.ptr.is_null());
+        expect_gt!(features.size, 0);
+    }
+}
diff --git a/rust/coverage/src/lib.rs b/rust/coverage/src/lib.rs
new file mode 100644
index 0000000..16eca13
--- /dev/null
+++ b/rust/coverage/src/lib.rs
@@ -0,0 +1,15 @@
+mod coverage;
+
+pub use coverage::SanCovRuntimeRawFeatureParts;
+
+pub fn prepare_coverage(full_clear: bool) {
+    coverage::SanCovRuntimeClearCoverage(full_clear)
+}
+
+pub fn get_coverage(reject_input: bool) -> SanCovRuntimeRawFeatureParts {
+    coverage::SanCovRuntimeGetCoverage(reject_input)
+}
+
+pub fn post_process_coverage(reject_input: bool) {
+    coverage::SanCovRuntimePostProcessCoverage(reject_input)
+}
diff --git a/rust/e2e_tests/BUILD b/rust/e2e_tests/BUILD
new file mode 100644
index 0000000..9ebb21b
--- /dev/null
+++ b/rust/e2e_tests/BUILD
@@ -0,0 +1,98 @@
+load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
+
+licenses(["notice"])
+
+rust_test(
+    name = "worker_test",
+    srcs = ["worker_test.rs"],
+    data = [
+        "@com_google_fuzztest//rust/e2e_tests/testdata:fuzztest_main",
+    ],
+    edition = "2024",
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+    ],
+)
+
+rust_test(
+    name = "standalone_mode_test",
+    srcs = ["standalone_mode_test.rs"],
+    data = [
+        "@com_google_fuzztest//centipede:centipede_uninstrumented",
+        "@com_google_fuzztest//rust/e2e_tests/testdata:fuzztest_main",
+        "@com_google_fuzztest//rust/e2e_tests/testdata:standalone_fuzz_tests_bin",
+    ],
+    edition = "2024",
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+    ],
+)
+
+rust_test(
+    name = "worker_with_centipede_test",
+    srcs = ["worker_with_centipede_test.rs"],
+    data = [
+        "@com_google_fuzztest//centipede:centipede_uninstrumented",
+        "@com_google_fuzztest//rust/e2e_tests/testdata:fuzztest_main",
+    ],
+    edition = "2024",
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+        "@crate_index//:rand",  # v0_10
+    ],
+)
+
+rust_test(
+    name = "worker_with_centipede_sanitizer_test",
+    srcs = ["worker_with_centipede_sanitizer_test.rs"],
+    data = [
+        "@com_google_fuzztest//centipede:centipede_uninstrumented",
+        "@com_google_fuzztest//rust/e2e_tests/testdata:fuzztest_main",
+    ],
+    edition = "2024",
+    rustc_flags = ["-Zallow-features=cfg_sanitize"],
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+    ],
+)
+
+rust_library(
+    name = "test_utils",
+    testonly = 1,
+    srcs = ["test_utils.rs"],
+    edition = "2024",
+    deps = [
+        "@crate_index//:googletest",
+    ],
+)
+
+rust_test(
+    name = "gtest_registration_test",
+    srcs = ["gtest_registration_test.rs"],
+    data = [
+        "@com_google_fuzztest//rust/e2e_tests/testdata:fuzz_tests_as_gtests",
+    ],
+    edition = "2024",
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+    ],
+)
+
+rust_test(
+    name = "replay_test",
+    srcs = ["replay_test.rs"],
+    data = [
+        "@com_google_fuzztest//centipede:centipede_uninstrumented",
+        "@com_google_fuzztest//rust/e2e_tests/testdata:replay_fuzz_tests_bin",
+    ],
+    edition = "2024",
+    deps = [
+        ":test_utils",
+        "@crate_index//:googletest",
+    ],
+)
diff --git a/rust/e2e_tests/gtest_registration_test.rs b/rust/e2e_tests/gtest_registration_test.rs
new file mode 100644
index 0000000..59e0b61
--- /dev/null
+++ b/rust/e2e_tests/gtest_registration_test.rs
@@ -0,0 +1,46 @@
+use googletest::matchers;
+use googletest::prelude::*;
+use std::env;
+use std::path::PathBuf;
+use std::process::Command;
+
+#[gtest]
+fn test_fuzztests_are_registered_as_gtests() {
+    let src_dir_path = PathBuf::from(env::var("TEST_SRCDIR").unwrap());
+    let target_binary_path = src_dir_path
+    .join("_main/rust/e2e_tests/testdata/fuzz_tests_as_gtests");
+
+    // Run the test binary with `--list` to list all registered tests.
+    let output = Command::new(&target_binary_path)
+        .arg("--list")
+        .output()
+        .expect("Failed to execute test binary");
+
+    assert!(output.status.success(), "Test binary failed to execute with --list");
+
+    let stdout = String::from_utf8_lossy(&output.stdout);
+
+    // Verify that the expected fuzz tests are listed as regular tests.
+    expect_that!(stdout, matchers::contains_substring("bool_fuzz_test: test"));
+    expect_that!(stdout, matchers::contains_substring("multi_arg_fuzz_test: test"));
+}
+
+#[gtest]
+fn test_fuzztest_property_function_executes_in_gtest() {
+    let src_dir_path = PathBuf::from(env::var("TEST_SRCDIR").unwrap());
+    let target_binary_path = src_dir_path
+    .join("_main/rust/e2e_tests/testdata/fuzz_tests_as_gtests");
+
+    // Run a fuzz test
+    let output = Command::new(&target_binary_path)
+        .arg("bool_fuzz_test")
+        .arg("--nocapture")
+        .output()
+        .expect("Failed to execute test binary");
+
+    assert!(output.status.success(), "Test binary failed to execute `bool_fuzz_test`");
+
+    let stdout = String::from_utf8_lossy(&output.stdout);
+
+    expect_that!(stdout, matchers::contains_substring("bool_fuzz_test property function ran..."));
+}
diff --git a/rust/e2e_tests/replay_test.rs b/rust/e2e_tests/replay_test.rs
new file mode 100644
index 0000000..cca56ce
--- /dev/null
+++ b/rust/e2e_tests/replay_test.rs
@@ -0,0 +1,144 @@
+use googletest::matchers;
+use googletest::prelude::*;
+use std::fs;
+use std::process::{Command, Stdio};
+use std::path::PathBuf;
+use test_utils::EnvVars;
+
+fn get_target_binary_path(fixture: &EnvVars) -> PathBuf {
+    std::env::var_os("CARGO_BIN_EXE_replay_fuzz_tests_bin").map(PathBuf::from).unwrap_or_else(
+        || {
+            fixture
+                .target_binary_path
+                .parent()
+                .expect("target_binary_path must have a parent")
+                .join("replay_fuzz_tests_bin")
+        },
+    )
+}
+
+#[gtest]
+fn replay_by_id_reproduces_panic(fixture: &EnvVars) {
+    let test_name = "__fuzztest_mod__find_two_bugs_fuzz_test::find_two_bugs_fuzz_test";
+    let normalized_test_name = test_name.replace("::", ".");
+
+    let target_binary_path = get_target_binary_path(fixture);
+    let target_binary_str = target_binary_path.to_str().expect("valid path string");
+    let binary_id = target_binary_str.strip_prefix('/').unwrap_or(target_binary_str);
+
+    let db_dir = fixture.tmp_dir_path.join("corpus_db");
+    fs::create_dir_all(&db_dir).expect("Failed to create db directory");
+
+    let workdir_root_dir = fixture.tmp_dir_path.join("workdir_root");
+    fs::create_dir_all(&workdir_root_dir).expect("Failed to workdir_root directory");
+
+    // 1. Run Centipede to fuzz the target and populate the corpus database.
+    Command::new(&target_binary_path)
+        .arg(test_name)
+        .arg("--exact")
+        .env("FUZZTEST_FUZZ_FOR", "30s")
+        .env("FUZZTEST_CORPUS_DB", &db_dir)
+        .env("FUZZTEST_WORKDIR_ROOT", &workdir_root_dir)
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .status()
+        .expect("Failed to spawn binary");
+
+    // 2. Retrieve the crash IDs from the corpus database using Centipede's --list_crash_ids flag.
+    let crash_ids_file = fixture.tmp_dir_path.join("crash_ids.txt");
+    let list_args = [
+        format!("--binary={}", target_binary_path.display()),
+        format!("--fuzztest_binary_identifier={}", binary_id),
+        format!("--test_name={}", normalized_test_name),
+        format!("--fuzztest_corpus_database={}", db_dir.display()),
+        "--list_crash_ids=1".to_string(),
+        format!("--list_crash_ids_file={}", crash_ids_file.display()),
+    ];
+    let list_args_refs: Vec<&str> = list_args.iter().map(|s| s.as_str()).collect();
+    test_utils::run_centipede_with_args_expect_termination(fixture, &list_args_refs);
+
+    let crash_ids_contents =
+        fs::read_to_string(&crash_ids_file).expect("Failed to read crash IDs file");
+    let crash_ids: Vec<&str> =
+        crash_ids_contents.lines().filter(|line| !line.trim().is_empty()).collect();
+
+    expect_that!(crash_ids.len(), eq(2));
+
+    // 3. Verify that replaying each crash ID reproduces a panic or segfault.
+    let mut reproduced_panic = false;
+    let mut reproduced_segfault = false;
+
+    for crash_id in &crash_ids {
+        let process = Command::new(&target_binary_path)
+            .arg(test_name)
+            .arg("--exact")
+            .arg("--nocapture")
+            .env("FUZZTEST_REPLAY_ID", crash_id)
+            .env("FUZZTEST_CORPUS_DB", &db_dir)
+            .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+            .stdout(Stdio::piped())
+            .stderr(Stdio::piped())
+            .spawn()
+            .expect("Failed to spawn binary");
+        let output = process.wait_with_output().expect("Should terminate");
+        let stderr = String::from_utf8_lossy(&output.stderr);
+
+        expect_that!(output.status.success(), eq(false));
+        expect_that!(stderr, matchers::contains_substring("FuzzTest controller reported failure"));
+
+        if stderr.contains("Bug 1 found!") {
+            reproduced_panic = true;
+        } else if stderr.contains("Bug 2 found!") {
+            reproduced_segfault = true;
+        }
+    }
+
+    expect_that!(reproduced_panic, eq(true));
+    expect_that!(reproduced_segfault, eq(true));
+}
+
+#[gtest]
+fn replay_all_reproduces_all_failures(fixture: &EnvVars) {
+    let test_name = "__fuzztest_mod__find_two_bugs_fuzz_test::find_two_bugs_fuzz_test";
+
+    let target_binary_path = get_target_binary_path(fixture);
+    let target_binary_str = target_binary_path.to_str().expect("valid path string");
+    let binary_id = target_binary_str.strip_prefix('/').unwrap_or(target_binary_str);
+
+    let db_dir = fixture.tmp_dir_path.join("corpus_db_all");
+    fs::create_dir_all(&db_dir).expect("Failed to create db directory");
+
+    let workdir_root_dir = fixture.tmp_dir_path.join("workdir_root");
+    fs::create_dir_all(&workdir_root_dir).expect("Failed to workdir_root directory");
+
+    // 1. Run Centipede to fuzz the target and populate the corpus database.
+    Command::new(&target_binary_path)
+        .arg(test_name)
+        .arg("--exact")
+        .env("FUZZTEST_FUZZ_FOR", "30s")
+        .env("FUZZTEST_CORPUS_DB", &db_dir)
+        .env("FUZZTEST_WORKDIR_ROOT", &workdir_root_dir)
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .status()
+        .expect("Failed to spawn binary");
+
+    // 2. Replay all findings using FUZZTEST_REPLAY_FINDINGS=true.
+    let process = Command::new(&target_binary_path)
+        .arg(test_name)
+        .arg("--exact")
+        .env("FUZZTEST_REPLAY_FINDINGS", "true")
+        .env("FUZZTEST_CORPUS_DB", &db_dir)
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .stdout(Stdio::piped())
+        .stderr(Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output = process.wait_with_output().expect("Should terminate");
+    let stderr = String::from_utf8_lossy(&output.stderr);
+
+    expect_that!(output.status.success(), eq(true));
+    expect_that!(stderr, matchers::contains_substring("Bug 1 found!"));
+    expect_that!(stderr, matchers::contains_substring("Bug 2 found!"));
+}
diff --git a/rust/e2e_tests/standalone_mode_test.rs b/rust/e2e_tests/standalone_mode_test.rs
new file mode 100644
index 0000000..adb5253
--- /dev/null
+++ b/rust/e2e_tests/standalone_mode_test.rs
@@ -0,0 +1,297 @@
+use googletest::matchers;
+use googletest::prelude::*;
+use std::process::Command;
+use test_utils::EnvVars;
+
+#[gtest]
+fn standalone_mode_invokes_centipede(fixture: &EnvVars) {
+    let target_binary_path =
+        fixture.target_binary_path.parent().unwrap().join("standalone_fuzz_tests_bin");
+    let test_name = "__fuzztest_mod__standalone_validation_test::standalone_validation_test";
+
+    let process = Command::new(&target_binary_path)
+        .arg(test_name)
+        .env("FUZZTEST_FUZZ_FOR", "3s")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output = process.wait_with_output().expect("Should terminate");
+    let stderr = String::from_utf8_lossy(&output.stderr);
+
+    // Assert that Centipede actually ran the test binary, and forwarded the worker log.
+    // We check for "LOG: STANDALONE_VALIDATION_WORKER_EXECUTED". The prefix "LOG: " indicates that
+    // this output is from centipede forwarding the output of the worker (due to --print_runner_log),
+    // whereas the rest is from the fuzztest itself.
+    expect_that!(
+        stderr,
+        matchers::contains_substring("LOG: STANDALONE_VALIDATION_WORKER_EXECUTED")
+    );
+}
+
+#[gtest]
+fn standalone_mode_invokes_the_correct_fuzztest(fixture: &EnvVars) {
+    let target_binary_path =
+        fixture.target_binary_path.parent().unwrap().join("standalone_fuzz_tests_bin");
+    let test_name = "__fuzztest_mod__standalone_validation_test::standalone_validation_test";
+
+    let process = Command::new(&target_binary_path)
+        .arg(test_name)
+        .env("FUZZTEST_FUZZ_FOR", "3s")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output = process.wait_with_output().expect("Should terminate");
+    let stderr = String::from_utf8_lossy(&output.stderr);
+
+    // Check that the first test is executed
+    expect_that!(
+        stderr,
+        matchers::contains_substring("LOG: STANDALONE_VALIDATION_WORKER_EXECUTED")
+    );
+
+    // Check that the second test does not get executed
+    expect_that!(stderr, not(matchers::contains_substring("SECOND_VALIDATION_TEST_EXECUTED")));
+}
+
+#[gtest]
+fn standalone_mode_handles_worker_crash(fixture: &EnvVars) {
+    let test_name = "__fuzztest_mod__find_bug_fuzz_test::find_bug_fuzz_test";
+
+    let process = Command::new(&fixture.target_binary_path)
+        .arg(test_name)
+        .env("FUZZTEST_FUZZ_FOR", "5s")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output = process.wait_with_output().expect("Should terminate");
+    let stderr = String::from_utf8_lossy(&output.stderr);
+
+    expect_that!(stderr, matchers::contains_substring("Property function ran but crashed."));
+    expect_that!(stderr, matchers::contains_regex("Signature[ \t]*: Unwinding panic"));
+    // Centipede prefixes logs from the crashing worker with "CRASH LOG: ".
+    expect_that!(stderr, matchers::contains_substring("CRASH LOG: Bug found!"));
+}
+
+#[gtest]
+fn standalone_mode_spawns_parallel_jobs(fixture: &EnvVars) {
+    let target_binary_path =
+        fixture.target_binary_path.parent().unwrap().join("standalone_fuzz_tests_bin");
+    let test_name = "__fuzztest_mod__jobs_test::jobs_test";
+
+    let process = Command::new(&target_binary_path)
+        .arg(test_name)
+        .env("FUZZTEST_FUZZ_FOR", "5s")
+        .env("FUZZTEST_JOBS", "4")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output = process.wait_with_output().expect("Should terminate");
+    let stderr = String::from_utf8_lossy(&output.stderr);
+
+    // Extract all PIDs from logs.
+    // Expected format: "LOG: JOBS_TEST_PID: <pid>"
+    use std::collections::HashSet;
+    let mut pids = HashSet::new();
+    for line in stderr.lines() {
+        if let Some(pos) = line.find("LOG: JOBS_TEST_PID: ") {
+            let pid_str = &line[pos + "LOG: JOBS_TEST_PID: ".len()..];
+            if let Ok(pid) = pid_str.parse::<u32>() {
+                pids.insert(pid);
+            }
+        }
+    }
+
+    // We expect 4 different PIDs
+    expect_that!(pids.len(), eq(4));
+}
+
+#[gtest]
+fn standalone_mode_replay_corpus_per_test_budget(fixture: &EnvVars) {
+    let target_binary_path =
+        fixture.target_binary_path.parent().unwrap().join("standalone_fuzz_tests_bin");
+
+    let corpus_db = fixture.tmp_dir_path.join("corpus_db_per_test");
+    let work_dir_root = fixture.tmp_dir_path.join("WD_root_per_test");
+
+    // Centipede appends the binary identifier (relative path) to the corpus database path.
+    let identifier = target_binary_path.to_str().unwrap();
+    let identifier_relative = identifier.strip_prefix('/').unwrap_or(identifier);
+
+    // Create corpus dirs for tests
+    let test1_dir = corpus_db
+        .join(identifier_relative)
+        .join("__fuzztest_mod__standalone_validation_test.standalone_validation_test")
+        .join("coverage");
+    let test2_dir = corpus_db
+        .join(identifier_relative)
+        .join("__fuzztest_mod__second_validation_test.second_validation_test")
+        .join("coverage");
+
+    std::fs::create_dir_all(&test1_dir).unwrap();
+    std::fs::create_dir_all(&test2_dir).unwrap();
+
+    // Write some corpus inputs.
+    // Assuming Arbitrary<i32> consumes 4 bytes.
+    use std::fs::File;
+    use std::io::Write;
+
+    let mut file1 = File::create(test1_dir.join("input1")).unwrap();
+    file1.write_all(&[1, 0, 0, 0]).unwrap();
+
+    let mut file2 = File::create(test1_dir.join("input2")).unwrap();
+    file2.write_all(&[2, 0, 0, 0]).unwrap();
+
+    let mut file3 = File::create(test2_dir.join("input3")).unwrap();
+    file3.write_all(&[3, 0, 0, 0]).unwrap();
+
+    let process_per_test = Command::new(&target_binary_path)
+        .arg("__fuzztest_mod__")
+        .env("FUZZTEST_REPLAY_CORPUS_FOR", "3s")
+        .env("FUZZTEST_TIME_BUDGET_TYPE", "per-test")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("FUZZTEST_CORPUS_DB", corpus_db.to_str().unwrap())
+        .env("FUZZTEST_WORKDIR_ROOT", work_dir_root.to_str().unwrap())
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output_per_test = process_per_test.wait_with_output().expect("Should terminate");
+    let stderr_per_test = String::from_utf8_lossy(&output_per_test.stderr);
+
+    // Verify logs for per-test
+    expect_that!(
+        stderr_per_test,
+        matchers::contains_substring("Replaying __fuzztest_mod__standalone_validation_test.standalone_validation_test for 3s")
+    );
+    expect_that!(
+        stderr_per_test,
+        matchers::contains_substring(
+            "Replaying __fuzztest_mod__second_validation_test.second_validation_test for 3s"
+        )
+    );
+
+    // Count executions for per-test
+    let mut val1_count = 0;
+    let mut val2_count = 0;
+    for line in stderr_per_test.lines() {
+        if line.contains("STANDALONE_VALIDATION_INPUT:") {
+            val1_count += 1;
+        }
+        if line.contains("SECOND_VALIDATION_INPUT:") {
+            val2_count += 1;
+        }
+    }
+    // we had 2 inputs for first test
+    expect_that!(val1_count, eq(2));
+    // and 1 input for second test
+    expect_that!(val2_count, eq(1));
+}
+
+#[gtest]
+fn standalone_mode_replay_corpus_total_budget(fixture: &EnvVars) {
+    let target_binary_path =
+        fixture.target_binary_path.parent().unwrap().join("standalone_fuzz_tests_bin");
+
+    let corpus_db = fixture.tmp_dir_path.join("corpus_db_total");
+    let work_dir_root = fixture.tmp_dir_path.join("WD_root_total");
+
+    // Centipede appends the binary identifier (relative path) to the corpus database path.
+    let identifier = target_binary_path.to_str().unwrap();
+    let identifier_relative = identifier.strip_prefix('/').unwrap_or(identifier);
+
+    // Create corpus dirs for tests
+    let test1_dir = corpus_db
+        .join(identifier_relative)
+        .join("__fuzztest_mod__standalone_validation_test.standalone_validation_test")
+        .join("coverage");
+    let test2_dir = corpus_db
+        .join(identifier_relative)
+        .join("__fuzztest_mod__second_validation_test.second_validation_test")
+        .join("coverage");
+
+    std::fs::create_dir_all(&test1_dir).unwrap();
+    std::fs::create_dir_all(&test2_dir).unwrap();
+
+    // Write some corpus inputs.
+    // Assuming Arbitrary<i32> consumes 4 bytes.
+    use std::fs::File;
+    use std::io::Write;
+
+    let mut file1 = File::create(test1_dir.join("input1")).unwrap();
+    file1.write_all(&[1, 0, 0, 0]).unwrap();
+
+    let mut file2 = File::create(test1_dir.join("input2")).unwrap();
+    file2.write_all(&[2, 0, 0, 0]).unwrap();
+
+    let mut file3 = File::create(test2_dir.join("input3")).unwrap();
+    file3.write_all(&[3, 0, 0, 0]).unwrap();
+
+    // We have 3 fuzz tests in the binary. Total 3s / 3 = 1s per test.
+    let process_total = Command::new(&target_binary_path)
+        .arg("__fuzztest_mod__")
+        .env("FUZZTEST_REPLAY_CORPUS_FOR", "3s")
+        .env("FUZZTEST_TIME_BUDGET_TYPE", "total")
+        .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true")
+        .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path)
+        .env("FUZZTEST_CORPUS_DB", corpus_db.to_str().unwrap())
+        .env("FUZZTEST_WORKDIR_ROOT", work_dir_root.to_str().unwrap())
+        .env("RUST_TEST_NOCAPTURE", "1")
+        .stdout(std::process::Stdio::piped())
+        .stderr(std::process::Stdio::piped())
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    let output_total = process_total.wait_with_output().expect("Should terminate");
+    let stderr_total = String::from_utf8_lossy(&output_total.stderr);
+
+    // Verify logs for total -> should be 1s
+    expect_that!(
+        stderr_total,
+        matchers::contains_substring("Replaying __fuzztest_mod__standalone_validation_test.standalone_validation_test for 1s")
+    );
+    expect_that!(
+        stderr_total,
+        matchers::contains_substring(
+            "Replaying __fuzztest_mod__second_validation_test.second_validation_test for 1s"
+        )
+    );
+
+    // Counts should still match because it finishes early anyway
+    let mut val1_count_total = 0;
+    let mut val2_count_total = 0;
+    for line in stderr_total.lines() {
+        if line.contains("STANDALONE_VALIDATION_INPUT:") {
+            val1_count_total += 1;
+        }
+        if line.contains("SECOND_VALIDATION_INPUT:") {
+            val2_count_total += 1;
+        }
+    }
+    // we had 2 inputs for first test
+    expect_that!(val1_count_total, eq(2));
+    // and 1 input for second test
+    expect_that!(val2_count_total, eq(1));
+}
diff --git a/rust/e2e_tests/test_utils.rs b/rust/e2e_tests/test_utils.rs
new file mode 100644
index 0000000..60044e7
--- /dev/null
+++ b/rust/e2e_tests/test_utils.rs
@@ -0,0 +1,66 @@
+use googletest::fixtures::Fixture;
+use std::env;
+use std::path::PathBuf;
+use std::process::Command;
+
+pub struct EnvVars {
+    pub tmp_dir_path: PathBuf,
+    pub target_binary_path: PathBuf,
+    pub centipede_path: PathBuf,
+}
+
+impl Fixture for EnvVars {
+    fn set_up() -> googletest::Result<Self> {
+        const TARGET_BINARY: &str =
+        "_main/rust/e2e_tests/testdata/fuzztest_main";
+
+        const CENTIPEDE: &str =
+        "_main/centipede/centipede_uninstrumented";
+        let src_dir_path = PathBuf::from(env::var("TEST_SRCDIR").unwrap());
+        let tmp_dir_path = PathBuf::from(env::var("TEST_TMPDIR").unwrap());
+        let target_binary_path = src_dir_path.join(PathBuf::from(TARGET_BINARY));
+        let centipede_path = src_dir_path.join(PathBuf::from(CENTIPEDE));
+
+        Ok(EnvVars { tmp_dir_path, target_binary_path, centipede_path })
+    }
+    fn tear_down(self) -> googletest::Result<()> {
+        Ok(())
+    }
+}
+
+/// Returns stderr of a Centipede process with `args` that is expected to terminate through some
+/// internal flag. e.g. `--exit_on_crash` or `--stop_after`.
+///
+/// Each arg of `args` should be a string that Centipede recognizes containing a flag with a
+/// possible value, e.g. `--test_name=my_test_name` or `--exit_on_crash`. In addition to `args`,
+/// the function will also pass `--populate_binary_info=0`, `--fork_server=0`,
+/// `--persistent_mode=0`, and `--env_diff_for_binaries`.
+pub fn run_centipede_with_args_expect_termination(fixture: &EnvVars, args: &[&str]) -> String {
+    // Disable interference from Bazel environment variables.
+    let env_diff = [
+        "-TEST_DIAGNOSTICS_OUTPUT_DIR",
+        "-TEST_INFRASTRUCTURE_FAILURE_FILE",
+        "-TEST_LOGSPLITTER_OUTPUT_FILE",
+        "-TEST_PREMATURE_EXIT_FILE",
+        "-TEST_RANDOM_SEED",
+        "-TEST_RUN_NUMBER",
+        "-TEST_SHARD_INDEX",
+        "-TEST_SHARD_STATUS_FILE",
+        "-TEST_TOTAL_SHARDS",
+        "-TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR",
+        "-TEST_UNDECLARED_OUTPUTS_DIR",
+        "-TEST_WARNINGS_OUTPUT_FILE",
+        "-GTEST_OUTPUT",
+        "-XML_OUTPUT_FILE",
+    ];
+    let process = Command::new(&fixture.centipede_path)
+        .arg("--populate_binary_info=0")
+        .arg("--fork_server=0")
+        .arg("--persistent_mode=0")
+        .arg(format!("--env_diff_for_binaries={}", env_diff.join(",")))
+        .args(args)
+        .output()
+        .expect("Centipede should have executed");
+
+    String::from_utf8_lossy(&process.stderr).to_string()
+}
diff --git a/rust/e2e_tests/testdata/BUILD b/rust/e2e_tests/testdata/BUILD
new file mode 100644
index 0000000..65111b2
--- /dev/null
+++ b/rust/e2e_tests/testdata/BUILD
@@ -0,0 +1,106 @@
+load("@rules_rust//rust:defs.bzl", "rust_test")
+
+package(default_visibility = ["@com_google_fuzztest//rust/e2e_tests:__subpackages__"])
+
+licenses(["notice"])
+
+rust_test(
+    name = "fuzztest_main",
+    testonly = 1,
+    srcs = [
+        "fuzz_tests.rs",
+    ],
+    edition = "2024",
+    # TODO: b/437896409 - Replace with global config once it's available.
+    rustc_flags = [
+        "-Ccodegen-units=1",
+        "-Clink-dead-code",
+        "-Cpasses=sancov-module",
+        "-Cllvm-args=-sanitizer-coverage-level=1",
+        "-Cllvm-args=-sanitizer-coverage-trace-compares",
+    ],
+    tags = [
+        "manual",
+        "notap",
+    ],
+    deps = [
+        "@crate_index//:googletest",
+        "@crate_index//:anyhow",  # v1
+        "@crate_index//:inventory",  # v0_3
+        "@crate_index//:rand",  # v0_10
+        "@com_google_fuzztest//rust:fuzztest",
+    ],
+)
+
+rust_test(
+    name = "standalone_fuzz_tests_bin",
+    testonly = 1,
+    srcs = [
+        "standalone_fuzz_tests.rs",
+    ],
+    edition = "2024",
+    rustc_flags = [
+        "-Ccodegen-units=1",
+        "-Clink-dead-code",
+        "-Cpasses=sancov-module",
+        "-Cllvm-args=-sanitizer-coverage-level=1",
+        "-Cllvm-args=-sanitizer-coverage-trace-compares",
+    ],
+    tags = [
+        "manual",
+        "notap",
+    ],
+    deps = [
+        "@crate_index//:googletest",
+        "@crate_index//:anyhow",  # v1
+        "@crate_index//:inventory",  # v0_3
+        "@crate_index//:rand",  # v0_10
+        "@com_google_fuzztest//rust:fuzztest",
+    ],
+)
+
+rust_test(
+    name = "replay_fuzz_tests_bin",
+    testonly = 1,
+    srcs = [
+        "replay_fuzz_tests.rs",
+    ],
+    edition = "2024",
+    rustc_flags = [
+        "-Ccodegen-units=1",
+        "-Clink-dead-code",
+        "-Cpasses=sancov-module",
+        "-Cllvm-args=-sanitizer-coverage-level=1",
+        "-Cllvm-args=-sanitizer-coverage-trace-compares",
+    ],
+    tags = [
+        "manual",
+        "notap",
+    ],
+    deps = [
+        "@crate_index//:googletest",
+        "@crate_index//:anyhow",  # v1
+        "@crate_index//:inventory",  # v0_3
+        "@crate_index//:rand",  # v0_10
+        "@com_google_fuzztest//rust:fuzztest",
+    ],
+)
+
+rust_test(
+    name = "fuzz_tests_as_gtests",
+    srcs = ["fuzz_tests_as_gtests.rs"],
+    edition = "2024",
+    rustc_flags = ["-Zallow-features=cfg_sanitize"],
+    tags = [
+        "manual",
+        "notap",
+    ],
+    deps = [
+        "@crate_index//:googletest",
+        "@crate_index//:anyhow",  # v1
+        "@crate_index//:inventory",  # v0_3
+        "@crate_index//:postcard",  # v1
+        "@crate_index//:rand",  # v0_10
+        "@com_google_fuzztest//rust:fuzztest",
+    ],
+)
diff --git a/rust/e2e_tests/testdata/fuzz_tests.rs b/rust/e2e_tests/testdata/fuzz_tests.rs
new file mode 100644
index 0000000..1a5e874
--- /dev/null
+++ b/rust/e2e_tests/testdata/fuzz_tests.rs
@@ -0,0 +1,171 @@
+use fuzztest::domains::arbitrary::Arbitrary;
+use fuzztest::domains::range::InRange;
+use fuzztest::domains::Domain;
+use fuzztest::fuzztest;
+use rand::RngExt;
+use std::mem::MaybeUninit;
+
+struct ByteVectorDomain {}
+
+impl ByteVectorDomain {
+    pub fn new() -> Self {
+        Self {}
+    }
+}
+
+// Test-only domain.
+impl Domain for ByteVectorDomain {
+    type UserValue<'user> = Vec<u8>;
+    type CorpusValue = Vec<u8>;
+
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        let mut val = vec![0u8; rng.random_range(0..100)];
+        rng.fill(&mut val[..]);
+        Ok(val)
+    }
+
+    fn mutate(
+        &self,
+        val: &mut Self::CorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        if only_shrink {
+            if rng.random::<f32>() < 0.05 && !val.is_empty() {
+                val.remove(rng.random_range(..val.len()));
+            }
+
+            for elem in val {
+                if *elem != 0 {
+                    *elem -= 1;
+                }
+            }
+
+            return Ok(());
+        }
+        if rng.random::<f32>() < 0.05 {
+            val.insert(rng.random_range(0..=val.len()), rng.random());
+        }
+
+        if rng.random::<f32>() < 0.05 && !val.is_empty() {
+            val.remove(rng.random_range(..val.len()));
+        }
+
+        let start = rng.random_range(0..=val.len());
+        let end = rng.random_range(start..=val.len());
+        rng.fill(&mut val[start..end]);
+
+        Ok(())
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        val: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(val.clone())
+    }
+}
+
+#[fuzztest(_a = Arbitrary::<bool>::default())]
+fn bool_fuzz_test(_a: bool) {}
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn i32_fuzz_test(_a: i32) {}
+
+#[fuzztest(
+    _a = Arbitrary::<i32>::default(),
+    _b = Arbitrary::<f32>::default(),
+    _c = Arbitrary::<bool>::default(),
+    _d = ByteVectorDomain::new()
+)]
+fn multi_arg_fuzz_test(_a: i32, _b: f32, _c: bool, _d: Vec<u8>) {}
+
+// Designed to fail in a "rare" instance.
+#[fuzztest(a = ByteVectorDomain::new())]
+fn find_bug_fuzz_test(a: Vec<u8>) {
+    if !a.is_empty() && a[0] == 123 {
+        panic!("Bug found!");
+    }
+}
+
+// Designed to fail in an even rarer instance to prove that coverage is working.
+#[fuzztest(a = ByteVectorDomain::new())]
+fn find_rarer_bug_fuzz_test(a: Vec<u8>) {
+    if a.len() == 5 && a[0] == b'P' && a[1] == b'a' && a[2] == b'N' && a[3] == b'i' && a[4] == b'C'
+    {
+        panic!("Bug found!");
+    }
+}
+
+#[fuzztest(a = ByteVectorDomain::new(), b = ByteVectorDomain::new())]
+fn find_rarer_bug_2_args_fuzz_test(a: Vec<u8>, b: Vec<u8>) {
+    if !a.is_empty() && a[0] >= 128 && !b.is_empty() && b[0] == 42 {
+        panic!("Bug found!");
+    }
+}
+
+#[fuzztest(a = ByteVectorDomain::new(), b = Arbitrary::<f32>::default(), c = InRange::<i32>::new(0, 100))]
+fn find_rarer_bug_3_args_fuzz_test(a: Vec<u8>, b: f32, c: i32) {
+    if !a.is_empty() && a[0] >= 128 && b < 0.0 && c >= 95 {
+        panic!("Bug found!");
+    }
+}
+#[fuzztest(a = ByteVectorDomain::new())]
+fn use_after_free_asan_death_test(mut a: Vec<u8>) {
+    if !a.is_empty() && a[0] == 123 {
+        let ptr = a.as_mut_ptr();
+        drop(a);
+        // Intentionally trigger a use-after-free bug for ASAN to detect.
+        unsafe {
+            *(std::hint::black_box(ptr)) = 1;
+        }
+    }
+}
+
+#[fuzztest(a = ByteVectorDomain::new())]
+fn msan_death_test(a: Vec<u8>) {
+    if !a.is_empty() && a[0] == 123 {
+        // Intentionally trigger an uninitialized memory bug for MSAN to detect.
+        unsafe {
+            let x: MaybeUninit<i32> = MaybeUninit::uninit();
+            let y = std::hint::black_box(x).assume_init();
+            println!("y: {}", y);
+        }
+    }
+}
+
+struct FallibleDomain {}
+
+impl FallibleDomain {
+    pub fn new() -> Self {
+        Self {}
+    }
+}
+
+impl Domain for FallibleDomain {
+    type UserValue<'user> = u32;
+    type CorpusValue = u32;
+
+    fn init(&self, _rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        Ok(0)
+    }
+
+    fn mutate(
+        &self,
+        _val: &mut Self::CorpusValue,
+        _rng: &mut dyn rand::Rng,
+        _only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        anyhow::bail!("Intentional mutate failure")
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        val: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(*val)
+    }
+}
+
+#[fuzztest(a = FallibleDomain::new())]
+fn fallible_fuzz_test(_a: u32) {}
diff --git a/rust/e2e_tests/testdata/fuzz_tests_as_gtests.rs b/rust/e2e_tests/testdata/fuzz_tests_as_gtests.rs
new file mode 100644
index 0000000..4e2ed7b
--- /dev/null
+++ b/rust/e2e_tests/testdata/fuzz_tests_as_gtests.rs
@@ -0,0 +1,18 @@
+use fuzztest::domains::arbitrary::Arbitrary;
+use fuzztest::fuzztest;
+use std::sync::Once;
+
+#[fuzztest(_a = Arbitrary::<bool>::default())]
+fn bool_fuzz_test(_a: bool) {
+    static ONCE: Once = Once::new();
+    ONCE.call_once(|| {
+        println!("bool_fuzz_test property function ran...");
+    });
+}
+
+#[fuzztest(
+    _a = Arbitrary::<i32>::default(),
+    _b = Arbitrary::<f32>::default(),
+    _c = Arbitrary::<bool>::default(),
+)]
+fn multi_arg_fuzz_test(_a: i32, _b: f32, _c: bool) {}
diff --git a/rust/e2e_tests/testdata/replay_fuzz_tests.rs b/rust/e2e_tests/testdata/replay_fuzz_tests.rs
new file mode 100644
index 0000000..7d664da
--- /dev/null
+++ b/rust/e2e_tests/testdata/replay_fuzz_tests.rs
@@ -0,0 +1,34 @@
+use fuzztest::domains::arbitrary::Arbitrary;
+use fuzztest::fuzztest;
+
+#[fuzztest(a = Arbitrary::<i32>::default())]
+fn find_bug_fuzz_test(a: i32) {
+    println!("PROPERTY_FUNCTION_EXECUTED");
+    if a == 10 || a == 20 || a == 30 {
+        panic!("Bug found!");
+    }
+}
+
+#[fuzztest(a = Arbitrary::<i32>::default())]
+fn find_two_bugs_fuzz_test(a: i32) {
+    println!("PROPERTY_FUNCTION_EXECUTED");
+    if a < -1 {
+        panic!("Bug 1 found!");
+    } else if a > 1 {
+        println!("Bug 2 found!");
+        // Safety: We are intentionally causing a segfault to test that the engine would catch it.
+        unsafe {
+            std::ptr::null_mut::<i32>().write_volatile(42);
+        }
+    }
+}
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn untargeted_test_1(_a: i32) {
+    println!("UNTARGETED_TEST_1_EXECUTED");
+}
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn untargeted_test_2(_a: i32) {
+    println!("UNTARGETED_TEST_2_EXECUTED");
+}
diff --git a/rust/e2e_tests/testdata/standalone_fuzz_tests.rs b/rust/e2e_tests/testdata/standalone_fuzz_tests.rs
new file mode 100644
index 0000000..e8d7d53
--- /dev/null
+++ b/rust/e2e_tests/testdata/standalone_fuzz_tests.rs
@@ -0,0 +1,21 @@
+use fuzztest::domains::arbitrary::Arbitrary;
+use fuzztest::fuzztest;
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn standalone_validation_test(_a: i32) {
+    // Minimal test function to validate standalone mode.
+    println!("STANDALONE_VALIDATION_WORKER_EXECUTED");
+    println!("STANDALONE_VALIDATION_INPUT: {}", _a);
+}
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn second_validation_test(_a: i32) {
+    println!("SECOND_VALIDATION_TEST_EXECUTED");
+    println!("SECOND_VALIDATION_INPUT: {}", _a);
+}
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn jobs_test(_a: i32) {
+    println!("JOBS_TEST_PID: {}", std::process::id());
+    std::thread::sleep(std::time::Duration::from_millis(250));
+}
diff --git a/rust/e2e_tests/worker_test.rs b/rust/e2e_tests/worker_test.rs
new file mode 100644
index 0000000..7676af5
--- /dev/null
+++ b/rust/e2e_tests/worker_test.rs
@@ -0,0 +1,26 @@
+use googletest::matchers;
+use googletest::prelude::*;
+use std::fs;
+use std::process::Command;
+use test_utils::EnvVars;
+
+#[gtest]
+fn get_binary_id_test(fixture: &EnvVars) {
+    let binary_id_file = fixture.tmp_dir_path.join("binary_id.txt");
+
+    let mut process = Command::new(&fixture.target_binary_path)
+        .env(
+            "CENTIPEDE_RUNNER_FLAGS",
+            format!(":dump_binary_id:binary_id_output={}:", binary_id_file.display()),
+        )
+        .spawn()
+        .expect("Failed to spawn binary");
+
+    process.wait().expect("Should terminate");
+    expect_that!(
+        fs::read_to_string(binary_id_file).unwrap(),
+        matchers::contains_substring(
+            (fixture.target_binary_path.file_name()).unwrap().to_string_lossy()
+        )
+    );
+}
diff --git a/rust/e2e_tests/worker_with_centipede_sanitizer_test.rs b/rust/e2e_tests/worker_with_centipede_sanitizer_test.rs
new file mode 100644
index 0000000..f4c1221
--- /dev/null
+++ b/rust/e2e_tests/worker_with_centipede_sanitizer_test.rs
@@ -0,0 +1,49 @@
+#![feature(cfg_sanitize)]
+
+#[cfg(any(sanitize = "address", sanitize = "memory"))]
+use googletest::matchers;
+#[cfg(any(sanitize = "address", sanitize = "memory"))]
+use googletest::prelude::*;
+#[cfg(any(sanitize = "address", sanitize = "memory"))]
+use std::fs;
+#[cfg(any(sanitize = "address", sanitize = "memory"))]
+use test_utils::EnvVars;
+
+#[gtest]
+#[cfg(sanitize = "address")]
+fn ensure_use_after_free_signature_with_asan(fixture: &EnvVars) {
+    let work_dir = fixture.tmp_dir_path.join("WD"); // For permissions
+    fs::create_dir_all(&work_dir).expect("Failed to create working directory");
+
+    let args = [
+        &format!("--binary={}", fixture.target_binary_path.display()),
+        &format!("--workdir={}", work_dir.display()),
+        "--exit_on_crash",
+        "--test_name=__fuzztest_mod__use_after_free_asan_death_test.use_after_free_asan_death_test",
+    ];
+
+    let stderr = test_utils::run_centipede_with_args_expect_termination(fixture, &args);
+
+    expect_that!(stderr, matchers::contains_regex("Signature[ \t]*: heap-use-after-free"));
+}
+
+// TODO(yamilmorales): Enable this test on presubmit with --config=msan.
+#[gtest]
+#[cfg(sanitize = "memory")]
+fn ensure_sanitizer_crash_signature_with_msan(fixture: &EnvVars) {
+    let work_dir = fixture.tmp_dir_path.join("WD"); // For permissions
+    fs::create_dir_all(&work_dir).expect("Failed to create working directory");
+
+    let args = [
+        &format!("--binary={}", fixture.target_binary_path.display()),
+        &format!("--workdir={}", work_dir.display()),
+        "--exit_on_crash",
+        "--test_name=__fuzztest_mod__msan_death_test.msan_death_test",
+        "--use_cmp_features=0", // Prevent msan from detecting nested bugs and aborting without
+                                // triggering the death callback.
+    ];
+
+    let stderr = test_utils::run_centipede_with_args_expect_termination(fixture, &args);
+
+    expect_that!(stderr, matchers::contains_regex("Signature[ \t]*: Sanitizer crash"));
+}
diff --git a/rust/e2e_tests/worker_with_centipede_test.rs b/rust/e2e_tests/worker_with_centipede_test.rs
new file mode 100644
index 0000000..4a16a7f
--- /dev/null
+++ b/rust/e2e_tests/worker_with_centipede_test.rs
@@ -0,0 +1,121 @@
+use googletest::matchers;
+use googletest::prelude::*;
+use rand::RngExt;
+use std::fs;
+use test_utils::EnvVars;
+
+fn run_centipede_test<'a>(
+    fixture: &EnvVars,
+    test_name: &str,
+    extra_args: impl IntoIterator<Item = &'a str>,
+) -> String {
+    let random_suffix: String =
+        rand::rng().sample_iter(&rand::distr::Alphanumeric).take(10).map(char::from).collect();
+    let work_dir_name = format!("WD_{}_{}", test_name, random_suffix);
+    let work_dir = fixture.tmp_dir_path.join(work_dir_name);
+    fs::create_dir_all(&work_dir).expect("Failed to create working directory");
+
+    let rust_test_name = test_name.replace(".", "::");
+    let mut args: Vec<String> = vec![
+        format!(
+            "--binary={} --nocapture {} --exact",
+            fixture.target_binary_path.display(),
+            rust_test_name
+        ),
+        format!("--workdir={}", work_dir.display()),
+        format!("--test_name={}", test_name),
+    ];
+    args.extend(extra_args.into_iter().map(|s| s.to_string()));
+
+    let args: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
+    test_utils::run_centipede_with_args_expect_termination(fixture, &args)
+}
+
+#[gtest]
+fn find_bug_with_centipede_test(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_bug_fuzz_test.find_bug_fuzz_test",
+        ["--exit_on_crash"],
+    );
+
+    expect_that!(stderr, matchers::contains_substring("Property function ran but crashed."));
+    expect_that!(stderr, matchers::contains_regex("Signature[ \t]*: Unwinding panic"));
+    expect_that!(stderr, matchers::contains_substring("CRASH LOG: Bug found!"));
+}
+
+#[gtest]
+fn ensure_custom_mutator_with_centipede_test(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_bug_fuzz_test.find_bug_fuzz_test",
+        ["--stop_after=10s"],
+    );
+
+    // In the 10 seconds that Centipede ran, the fuzzing loop should have requested to mutate.
+    expect_that!(stderr, matchers::contains_substring("Custom mutator detected"));
+}
+
+#[gtest]
+fn ensure_seed_emition_with_centipede_test(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_bug_fuzz_test.find_bug_fuzz_test",
+        ["--exit_on_crash", "--require_seeds"],
+    );
+
+    // If not present, then exited early because no seeds were emitted.
+    expect_that!(stderr, matchers::contains_substring("Number of input seeds available"));
+}
+
+#[gtest]
+fn ensure_features_work_finding_rarer_bug(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_rarer_bug_fuzz_test.find_rarer_bug_fuzz_test",
+        ["--exit_on_crash"],
+    );
+
+    // Centipede's passes a length-prefixed screen, so the initial \\\\x5 stands for
+    // that length, not any kind of hex-escaping.
+    expect_that!(stderr, matchers::contains_regex("Input bytes[ \t]*: \\\\x5PaNiC"));
+    expect_that!(stderr, matchers::contains_substring("CRASH LOG: Bug found!"));
+}
+
+#[gtest]
+fn ensure_features_work_finding_rarer_bug_2_args(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_rarer_bug_2_args_fuzz_test.find_rarer_bug_2_args_fuzz_test",
+        ["--exit_on_crash"],
+    );
+
+    expect_that!(stderr, matchers::contains_substring("CRASH LOG: Bug found!"));
+}
+
+#[gtest]
+fn ensure_features_work_finding_rarer_bug_3_args(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__find_rarer_bug_3_args_fuzz_test.find_rarer_bug_3_args_fuzz_test",
+        ["--exit_on_crash"],
+    );
+
+    expect_that!(stderr, matchers::contains_substring("CRASH LOG: Bug found!"));
+}
+
+#[gtest]
+fn ensure_emit_error_with_centipede_test(fixture: &EnvVars) {
+    let stderr = run_centipede_test(
+        fixture,
+        "__fuzztest_mod__fallible_fuzz_test.fallible_fuzz_test",
+        ["--stop_after=5s"],
+    );
+
+    expect_that!(
+        stderr,
+        matchers::contains_substring(
+            "Emitted failure output: Failed to mutate: Intentional mutate failure"
+        )
+    );
+}
diff --git a/rust/engine/BUILD b/rust/engine/BUILD
new file mode 100644
index 0000000..8004b3b
--- /dev/null
+++ b/rust/engine/BUILD
@@ -0,0 +1,18 @@
+load("@rules_rust//rust:defs.bzl", "rust_library")
+
+licenses(["notice"])
+
+rust_library(
+    name = "engine",
+    srcs = [
+        "src/engine_ffi.rs",
+        "src/lib.rs",
+    ],
+    deps = [
+        "@com_google_fuzztest//centipede:engine_abi",
+        "@com_google_fuzztest//centipede:engine_controller_with_subprocess",
+        "@com_google_fuzztest//centipede:engine_worker",
+    ],
+    edition = "2024",
+    visibility = ["@com_google_fuzztest//rust:__subpackages__"],
+)
diff --git a/rust/engine/Cargo.toml b/rust/engine/Cargo.toml
new file mode 100644
index 0000000..5f3c5c2
--- /dev/null
+++ b/rust/engine/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "engine-ffi"
+version = "0.1.0"
+edition = "2024"
+build = "build.rs"
+
+[dependencies]
+
+
diff --git a/rust/engine/build.rs b/rust/engine/build.rs
new file mode 100644
index 0000000..a1984ff
--- /dev/null
+++ b/rust/engine/build.rs
@@ -0,0 +1,37 @@
+//! Build script for the `engine-ffi` crate.
+//!
+//! ## Prerequisites
+//!
+//! Before compiling or testing this crate using Cargo (`cargo build` or `cargo test`),
+//! you must first compile the C++ Centipede dependencies using Bazel (or Blaze):
+//!
+//! ```bash
+//! bazel build //centipede:centipede_engine_static
+//! ```
+//!
+//! This command generates the required static library archive `libcentipede_engine_static.a`
+//! under `bazel-bin/centipede` (or `blaze-bin/centipede`).
+//!
+//! You can provide the directory path containing this library via `FUZZTEST_LIB_PATH`:
+//!
+//! ```bash
+//! FUZZTEST_LIB_PATH="bazel-bin/centipede" cargo build
+//! ```
+
+fn main() {
+    // Re-run this build script if FUZZTEST_LIB_PATH changes.
+    println!("cargo:rerun-if-env-changed=FUZZTEST_LIB_PATH");
+
+    // Add native library search path if FUZZTEST_LIB_PATH is provided.
+    if let Ok(lib_dir) = std::env::var("FUZZTEST_LIB_PATH") {
+        println!("cargo:rustc-link-search=native={lib_dir}");
+    }
+
+    println!("cargo:rustc-link-lib=static=centipede_engine_static");
+
+    // Link required system libraries
+    println!("cargo:rustc-link-lib=dylib=stdc++");
+    println!("cargo:rustc-link-lib=dylib=rt");
+    println!("cargo:rustc-link-lib=dylib=dl");
+    println!("cargo:rustc-link-lib=dylib=pthread");
+}
diff --git a/rust/engine/src/engine_ffi.rs b/rust/engine/src/engine_ffi.rs
new file mode 100644
index 0000000..0d63ae9
--- /dev/null
+++ b/rust/engine/src/engine_ffi.rs
@@ -0,0 +1,441 @@
+// The source of truth for the FFI definitions in this file are these C++ header files:
+// - engine_abi.h
+// - engine_worker_abi.h
+// - engine_controller_abi.h
+// TODO(b/540347807): use crubit
+
+use core::ffi::c_int;
+
+use core::marker::PhantomData;
+use core::marker::PhantomPinned;
+use core::ptr;
+
+// Opaque handles for in-memory input objects used by the test, which
+// may be serialized/deserialized by the engine.
+#[repr(transparent)]
+pub struct FuzzTestInputHandle(pub usize);
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct FuzzTestBytesView {
+    pub data: *const u8,
+    pub size: usize,
+}
+
+impl FuzzTestBytesView {
+    pub fn from_bytes(bytes: &[u8]) -> Self {
+        Self { data: bytes.as_ptr(), size: bytes.len() }
+    }
+
+    pub fn to_bytes(&self) -> *const [u8] {
+        if self.data.is_null() {
+            &[]
+        } else {
+            ptr::slice_from_raw_parts(self.data, self.size)
+        }
+    }
+}
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct FuzzTestBytesViews {
+    pub views: *const FuzzTestBytesView,
+    pub count: usize,
+}
+
+impl FuzzTestBytesViews {
+    pub fn from_slice(views: &[FuzzTestBytesView]) -> Self {
+        Self { views: views.as_ptr(), count: views.len() }
+    }
+
+    pub fn as_slice(&self) -> *const [FuzzTestBytesView] {
+        if self.views.is_null() {
+            &[]
+        } else {
+            ptr::slice_from_raw_parts(self.views, self.count)
+        }
+    }
+}
+
+#[repr(C)]
+pub struct FuzzTestDiagnosticSinkCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+/// Sink for diagnostics during the setup and execution of the test
+/// methods. Methods in this sink are async-safe and thread-safe.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct FuzzTestDiagnosticSink {
+    pub ctx: *mut FuzzTestDiagnosticSinkCtx,
+
+    /// Emits an unrecoverable error with a human-readable `message`. Engine would
+    /// propagate the error to the controller command when in the worker mode.
+    pub emit_error: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestDiagnosticSinkCtx,
+            message: *const FuzzTestBytesView,
+        ),
+    >,
+
+    /// Emits a warning with a human-readable `message`. Engine would log
+    /// the warning and continue gracefully when in the worker mode.
+    pub emit_warning: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestDiagnosticSinkCtx,
+            message: *const FuzzTestBytesView,
+        ),
+    >,
+
+    /// Emits a finding for running a test input within `Execute()` with a
+    /// human-readable `description`, and `signature` for deduplication.
+    ///
+    /// Must not be called if the engine is not calling `Execute()`. If called
+    /// multiple times within the same `Execute()` window, a random one would take
+    /// effect.
+    pub emit_finding: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestDiagnosticSinkCtx,
+            description: *const FuzzTestBytesView,
+            signature: *const FuzzTestBytesView,
+        ),
+    >,
+}
+
+// SAFETY: The engine guarantees that the diagnostic sink and its context are
+// thread-safe and async-safe.
+unsafe impl Send for FuzzTestDiagnosticSink {}
+unsafe impl Sync for FuzzTestDiagnosticSink {}
+
+#[repr(C)]
+pub struct FuzzTestBytesSinkCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+/// Sink for bytes data.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct FuzzTestBytesSink {
+    pub ctx: *mut FuzzTestBytesSinkCtx,
+
+    /// Emits a byte buffer. Multiple emissions are concatenated.
+    pub emit: Option<
+        unsafe extern "C" fn(ctx: *mut FuzzTestBytesSinkCtx, view: *const FuzzTestBytesView),
+    >,
+}
+
+#[repr(C)]
+pub struct FuzzTestInputSinkCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+/// Sink for seed inputs.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct FuzzTestInputSink {
+    pub ctx: *mut FuzzTestInputSinkCtx,
+
+    /// Emits a test `input` to the engine. Engine would call
+    /// `FuzzTestAdapter::FreeInput` on the emitted input after the engine is
+    /// done with it.
+    pub emit:
+        Option<unsafe extern "C" fn(ctx: *mut FuzzTestInputSinkCtx, input: FuzzTestInputHandle)>,
+}
+
+#[repr(C)]
+pub struct FuzzTestUint64sView {
+    pub data: *const u64,
+    pub size: usize,
+}
+
+impl FuzzTestUint64sView {
+    pub fn from_slice(slice: &[u64]) -> Self {
+        Self { data: slice.as_ptr(), size: slice.len() }
+    }
+
+    pub fn as_slice(&self) -> *const [u64] {
+        if self.data.is_null() || self.size == 0 {
+            &[]
+        } else {
+            ptr::slice_from_raw_parts(self.data, self.size)
+        }
+    }
+
+    pub fn to_bytes(&self) -> *const [u8] {
+        if self.data.is_null() {
+            &[]
+        } else {
+            ptr::slice_from_raw_parts(
+                self.data as *const u8,
+                self.size * core::mem::size_of::<u64>(),
+            )
+        }
+    }
+}
+/// Constants for the layout of the coverage feature as a 64-bit unsigned
+/// integer:
+///
+///   - Bits 63..59: 5-bit domain ID of the feature. Each domain is a
+///     logically independent feature namespace registered in
+///     `FuzzTestAdapter::SetUpCoverageDomains`.
+///   - Bits 58..32: 27-bit feature ID within the domain.
+///   - Bits 31..0:  32-bit counter value of the feature.
+///
+pub struct FuzzTestCoverageFeatureLayout;
+
+impl FuzzTestCoverageFeatureLayout {
+    pub const COUNTER_START_BIT: u32 = 0;
+    pub const COUNTER_BIT_SIZE: u32 = 32;
+    pub const FEATURE_ID_START_BIT: u32 = 32;
+    pub const FEATURE_ID_BIT_SIZE: u32 = 27;
+    pub const DOMAIN_ID_START_BIT: u32 = 59;
+    pub const DOMAIN_ID_BIT_SIZE: u32 = 5;
+}
+
+#[repr(C)]
+pub struct FuzzTestFeedbackSinkCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+/// Sink for execution feedback.
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct FuzzTestFeedbackSink {
+    pub ctx: *mut FuzzTestFeedbackSinkCtx,
+
+    /// Emits an array of coverage features captured from the execution
+    /// inside `Execute` call. See `FuzzTestCoverageFeatureLayout` for the feature
+    /// layout.
+    ///
+    /// Multiple emissions are concatenated.
+    pub emit_coverage_features: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestFeedbackSinkCtx,
+            features: *const FuzzTestUint64sView,
+        ),
+    >,
+}
+
+/// Information of a coverage domain.
+#[repr(C)]
+pub struct FuzzTestCoverageDomain {
+    /// 5-bit domain ID.
+    pub domain_id: u8,
+    /// Human-readable name of the domain for logging.
+    pub name: FuzzTestBytesView,
+    /// Number of bits used for the feature IDs in this domain, must be <= 27.
+    pub feature_id_bit_size: u8,
+    /// Number of bits used for the counter values in this domain, must be <= 32.
+    pub counter_bit_size: u8,
+}
+
+#[repr(C)]
+pub struct FuzzTestDomainRegistryCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct FuzzTestCoverageDomainRegistry {
+    pub ctx: *mut FuzzTestDomainRegistryCtx,
+
+    /// Registers a new coverage `domain`.
+    pub register: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestDomainRegistryCtx,
+            domain: *const FuzzTestCoverageDomain,
+        ),
+    >,
+}
+
+#[repr(C)]
+pub struct FuzzTestAdapterCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+#[repr(C)]
+pub struct FuzzTestAdapter {
+    pub ctx: *mut FuzzTestAdapterCtx,
+
+    /// Sets up coverage domains using the domain `registry`.
+    /// The domain registrations must be the same for the all the test adapters of
+    /// the same test (identified by the test name and the binary).
+    pub set_up_coverage_domains: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            registry: *const FuzzTestCoverageDomainRegistry,
+        ),
+    >,
+
+    /// [Optional] Emits any preset seed inputs of the test using `sink`.
+    /// The output must be the same for the all the test adapters of the same test
+    /// (identified by the test name and the binary).
+    pub get_preset_seed_inputs:
+        Option<unsafe extern "C" fn(ctx: *mut FuzzTestAdapterCtx, sink: *const FuzzTestInputSink)>,
+
+    /// Emits a randomly generated seed input using `sink`.
+    pub get_random_seed_input:
+        Option<unsafe extern "C" fn(ctx: *mut FuzzTestAdapterCtx, sink: *const FuzzTestInputSink)>,
+
+    /// Mutates from `origin`, and emits the mutant using `sink`. `shrink` != 0
+    /// means to generate smaller mutant.
+    ///
+    /// It should not change the content/metadata of `origin`.
+    pub mutate: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            origin: FuzzTestInputHandle,
+            shrink: c_int,
+            sink: *const FuzzTestInputSink,
+        ),
+    >,
+
+    /// [Optional] Performs cross-over mutation using `origin` and `other`, and
+    /// emits the mutant using `sink`.
+    ///
+    /// It should not change the content/metadata of `origin` or `other`.
+    pub cross_over: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            origin: FuzzTestInputHandle,
+            other: FuzzTestInputHandle,
+            sink: *const FuzzTestInputSink,
+        ),
+    >,
+
+    /// Executes `input` for testing and emits any feedback to `sink`.
+    ///
+    /// The `input` metadata may be updated by the adapter for further
+    /// mutations. The `input` content, which affects the test behavior of
+    /// `Execute()`, should not be changed.
+    pub execute: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            input: FuzzTestInputHandle,
+            sink: *const FuzzTestFeedbackSink,
+        ),
+    >,
+
+    /// Serializes the test `input` content into bytes using `sink`.
+    pub serialize_input_content: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            input: FuzzTestInputHandle,
+            sink: *const FuzzTestBytesSink,
+        ),
+    >,
+
+    /// Deserializes the test `input` content from serialized `content` into
+    /// a `FuzzTestInputHandle` using `sink`.
+    pub deserialize_input_content: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            content: *const FuzzTestBytesView,
+            sink: *const FuzzTestInputSink,
+        ),
+    >,
+
+    /// [Optional] Serializes the test `input` metadata into bytes using `sink`.
+    pub serialize_input_metadata: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            input: FuzzTestInputHandle,
+            sink: *const FuzzTestBytesSink,
+        ),
+    >,
+
+    /// [Optional] Updates the test `input` metadata from serialized `metadata`.
+    pub update_input_metadata: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterCtx,
+            metadata: *const FuzzTestBytesView,
+            input: FuzzTestInputHandle,
+        ),
+    >,
+
+    /// Callback to run when the engine is done with `input`.
+    pub free_input:
+        Option<unsafe extern "C" fn(ctx: *mut FuzzTestAdapterCtx, input: FuzzTestInputHandle)>,
+
+    /// Callback to run when the engine is done with `ctx` (and the adapter).
+    pub free_ctx: Option<unsafe extern "C" fn(ctx: *mut FuzzTestAdapterCtx)>,
+}
+
+#[repr(C)]
+pub struct FuzzTestAdapterManagerCtx {
+    _opaque: (),
+    _not_send_nor_sync: PhantomData<*mut ()>,
+    _not_unpin: PhantomPinned,
+}
+
+#[repr(C)]
+pub struct FuzzTestAdapterManager {
+    pub ctx: *mut FuzzTestAdapterManagerCtx,
+
+    /// [Optional] Emits the ID for the current binary.
+    pub get_binary_id: Option<
+        unsafe extern "C" fn(ctx: *mut FuzzTestAdapterManagerCtx, sink: *const FuzzTestBytesSink),
+    >,
+
+    /// Emits the test name.
+    pub get_test_name: Option<
+        unsafe extern "C" fn(ctx: *mut FuzzTestAdapterManagerCtx, sink: *const FuzzTestBytesSink),
+    >,
+
+    /// Constructs an adapter of the test into `adapter_out`. Any diagnostics
+    /// happening during the construction or running the adapter should be emitted
+    /// to `diagnostic_sink`. `diagnostic_sink` is guaranteed to live until
+    /// `FreeCtx` is called on the adapter.
+    pub construct_adapter: Option<
+        unsafe extern "C" fn(
+            ctx: *mut FuzzTestAdapterManagerCtx,
+            diagnostic_sink: *const FuzzTestDiagnosticSink,
+            adapter_out: *mut FuzzTestAdapter,
+        ),
+    >,
+}
+
+#[repr(i32)]
+pub enum FuzzTestWorkerStatus {
+    /// Test should finish with a success.
+    Success = 0,
+    /// Test should finish with a failure.
+    Failure = 1,
+    /// Test should continue with controller commands.
+    NotRequired = 2,
+}
+
+#[derive(PartialEq, Eq)]
+#[repr(i32)]
+pub enum FuzzTestControllerStatus {
+    Success = 0,
+    Failure = 1,
+}
+
+#[allow(improper_ctypes)]
+unsafe extern "C" {
+    /// Try to run as a FuzzTest worker with `manager` if needed.
+    pub fn FuzzTestWorkerMaybeRun(manager: *const FuzzTestAdapterManager) -> FuzzTestWorkerStatus;
+
+    /// Returns whether the current process is running as a FuzzTest worker -
+    /// non-zero means yes and zero means no. It can be called outside of tests.
+    pub fn FuzzTestWorkerIsRequired() -> c_int;
+
+    /// Run the FuzzTest controller with `flags` and `manager`.
+    pub fn FuzzTestControllerRun(
+        manager: *const FuzzTestAdapterManager,
+        flags: *const FuzzTestBytesViews,
+    ) -> FuzzTestControllerStatus;
+}
diff --git a/rust/engine/src/lib.rs b/rust/engine/src/lib.rs
new file mode 100644
index 0000000..7594c50
--- /dev/null
+++ b/rust/engine/src/lib.rs
@@ -0,0 +1,268 @@
+pub mod engine_ffi;
+
+use std::marker::PhantomData;
+
+#[allow(improper_ctypes)]
+unsafe extern "C" {
+    fn SanCovRuntimeSetUpCoverageDomains(
+        registry: *const engine_ffi::FuzzTestCoverageDomainRegistry,
+    ) -> usize;
+
+    fn SanCovRuntimeEmitFeatures(sink: *const engine_ffi::FuzzTestFeedbackSink);
+}
+
+/// A zero-sized witness token proving that a test is currently executing.
+///
+/// Some of the methods on FuzzTestDiagnosticSink require that they are called only if the engine is
+/// calling `Execute` callback of FuzzTestAdapter, which includes:
+///
+/// * `emit_finding`
+///
+/// The methods receiving this type can safely assume that the `Execute` callback is active because
+/// the caller ensures this by creating this type.
+pub struct ExecuteContext {
+    _private: PhantomData<()>,
+}
+
+impl ExecuteContext {
+    /// Creates a new execution context.
+    ///
+    /// # Safety
+    ///
+    /// * The caller must ensure that it is in the `Execute` callback of FuzzTestAdapter.
+    pub unsafe fn new() -> Self {
+        Self { _private: PhantomData }
+    }
+}
+
+#[derive(Clone)]
+pub struct DiagnosticSink {
+    raw: engine_ffi::FuzzTestDiagnosticSink,
+}
+
+impl DiagnosticSink {
+    /// Creates a safe wrapper from a pointer to `FuzzTestDiagnosticSink`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that:
+    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestDiagnosticSink`.
+    /// * `(*raw).ctx` is a valid context pointer.
+    /// * The sink and its context remain valid for the duration of `DiagnosticSink`'s usage
+    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
+    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestDiagnosticSink) -> Self {
+        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestDiagnosticSink`.
+        let raw_sink = unsafe { *raw };
+        Self { raw: raw_sink }
+    }
+
+    /// Emits an unrecoverable error message to the underlying diagnostic sink.
+    pub fn emit_error(&self, message: &str) {
+        let emit = self.raw.emit_error.expect("EmitError is required by ABI");
+        let view = engine_ffi::FuzzTestBytesView::from_bytes(message.as_bytes());
+        // SAFETY: The presence of `self` guarantees that the context of the underlying
+        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
+        unsafe {
+            emit(self.raw.ctx, &view);
+        }
+    }
+
+    /// Emits a warning message to the underlying diagnostic sink.
+    pub fn emit_warning(&self, message: &str) {
+        let emit = self.raw.emit_warning.expect("EmitWarning is required by ABI");
+        let view = engine_ffi::FuzzTestBytesView::from_bytes(message.as_bytes());
+        // SAFETY: The presence of `self` guarantees that the context of the underlying
+        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
+        unsafe {
+            emit(self.raw.ctx, &view);
+        }
+    }
+
+    /// Emits a test finding (e.g., a crash or bug) to the underlying diagnostic sink.
+    ///
+    /// This must only be called during test execution, which is guaranteed by the
+    /// [`ExecuteContext`] token.
+    pub fn emit_finding(&self, _token: &ExecuteContext, description: &str, signature: &str) {
+        let emit = self.raw.emit_finding.expect("EmitFinding is required by ABI");
+        let desc_view = engine_ffi::FuzzTestBytesView::from_bytes(description.as_bytes());
+        let sig_view = engine_ffi::FuzzTestBytesView::from_bytes(signature.as_bytes());
+        // SAFETY: The presence of `self` guarantees that the context of the underlying
+        // `FuzzTestDiagnosticSink` remains live for the duration of this sink.
+        // The witness `_token` further proves execution is currently within the `Execute` callback.
+        unsafe {
+            emit(self.raw.ctx, &desc_view, &sig_view);
+        }
+    }
+}
+
+pub struct BytesSink {
+    raw: engine_ffi::FuzzTestBytesSink,
+}
+
+impl BytesSink {
+    /// Creates a safe wrapper from a pointer to `FuzzTestBytesSink`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that:
+    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestBytesSink`.
+    /// * `(*raw).ctx` is a valid context pointer.
+    /// * The sink and its context remain valid for the duration of `BytesSink`'s usage
+    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
+    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestBytesSink) -> Self {
+        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestBytesSink`.
+        let raw_sink = unsafe { *raw };
+        Self { raw: raw_sink }
+    }
+
+    /// Emits a byte slice to the underlying bytes sink.
+    ///
+    /// Multiple calls to this function will concatenate the emitted bytes.
+    pub fn emit(&mut self, bytes: &[u8]) {
+        let emit = self.raw.emit.expect("Emit is required by ABI");
+        let view = engine_ffi::FuzzTestBytesView::from_bytes(bytes);
+        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
+        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
+        unsafe {
+            emit(self.raw.ctx, &view);
+        }
+    }
+}
+
+pub struct InputSink {
+    raw: engine_ffi::FuzzTestInputSink,
+}
+
+impl InputSink {
+    /// Creates a safe wrapper from a pointer to `FuzzTestInputSink`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that:
+    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestInputSink`.
+    /// * `(*raw).ctx` is a valid context pointer.
+    /// * The sink and its context remain valid for the duration of `InputSink`'s usage
+    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
+    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestInputSink) -> Self {
+        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestInputSink`.
+        let raw_sink = unsafe { *raw };
+        Self { raw: raw_sink }
+    }
+
+    /// Emits a test input handle to the underlying input sink.
+    ///
+    /// This function transfers ownership of the input represented by the handle
+    /// to the engine. The engine is responsible for freeing it.
+    pub fn emit(&mut self, input: engine_ffi::FuzzTestInputHandle) {
+        let emit = self.raw.emit.expect("Emit is required by ABI");
+        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
+        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
+        unsafe {
+            emit(self.raw.ctx, input);
+        }
+    }
+}
+
+pub struct FeedbackSink {
+    raw: engine_ffi::FuzzTestFeedbackSink,
+}
+
+impl FeedbackSink {
+    /// Creates a safe wrapper from a pointer to `FuzzTestFeedbackSink`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that:
+    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestFeedbackSink`.
+    /// * `(*raw).ctx` is a valid context pointer.
+    /// * The sink and its context remain valid for the duration of `FeedbackSink`'s usage
+    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
+    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestFeedbackSink) -> Self {
+        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestFeedbackSink`.
+        let raw_sink = unsafe { *raw };
+        Self { raw: raw_sink }
+    }
+
+    /// Emits execution coverage features to the underlying feedback sink.
+    pub fn emit_coverage_features(&mut self, features: &[u64]) {
+        let emit =
+            self.raw.emit_coverage_features.expect("EmitCoverageFeatures is required by ABI");
+        let view = engine_ffi::FuzzTestUint64sView::from_slice(features);
+        // SAFETY: The presence of `self` guarantees `from_raw` was called with a valid context
+        // pointer (`self.raw.ctx`) that remains live for the duration of this call.
+        unsafe {
+            emit(self.raw.ctx, &view);
+        }
+    }
+
+    /// Emits SanitizerCoverage features.
+    pub fn emit_sancov_features(&mut self) {
+        // SAFETY: the sink pointer is guaranteed to be valid by the framework.
+        unsafe { SanCovRuntimeEmitFeatures(&self.raw) };
+    }
+}
+
+/// Information describing a coverage feature domain.
+///
+/// This is a high-level  wrapper for [`engine_ffi::FuzzTestCoverageDomain`],
+/// which is the Rust representation of the C struct `FuzzTestCoverageDomain`
+/// defined in `engine_abi.h` (the source of truth for the ABI).
+///
+/// Unlike the FFI representation which uses [`engine_ffi::FuzzTestBytesView`],
+/// this type uses Rust slices (`&[u8]`) for safety and convenience. It can be
+/// converted to the FFI representation using `From`/`Into`.
+///
+/// A coverage domain represents a logically independent feature namespace registered in
+/// `CoverageDomainRegistry`. FuzzTest packs 64-bit coverage features into three parts:
+/// * Bits 63..59 (5 bits): 5-bit domain ID (`domain_id`, up to 32 domains).
+/// * Bits 58..32 (27 bits): Feature ID within the domain (`feature_id_bit_size` <= 27).
+/// * Bits 31..0 (32 bits): Feature counter value (`counter_bit_size` <= 32).
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub struct CoverageDomain<'a> {
+    /// 5-bit unique domain identifier (must be < 32).
+    pub domain_id: u8,
+    /// Human-readable name of the domain for logging and debugging.
+    pub name: &'a str,
+    /// Number of bits used for feature IDs in this domain (must be <= 27).
+    pub feature_id_bit_size: u8,
+    /// Number of bits used for feature counter values in this domain (must be <= 32).
+    pub counter_bit_size: u8,
+}
+
+impl<'a> From<CoverageDomain<'a>> for engine_ffi::FuzzTestCoverageDomain {
+    fn from(domain: CoverageDomain<'a>) -> Self {
+        Self {
+            domain_id: domain.domain_id,
+            name: engine_ffi::FuzzTestBytesView::from_bytes(domain.name.as_bytes()),
+            feature_id_bit_size: domain.feature_id_bit_size,
+            counter_bit_size: domain.counter_bit_size,
+        }
+    }
+}
+
+pub struct CoverageDomainRegistry {
+    raw: engine_ffi::FuzzTestCoverageDomainRegistry,
+}
+
+impl CoverageDomainRegistry {
+    /// Creates a safe wrapper from a pointer to `FuzzTestCoverageDomainRegistry`.
+    ///
+    /// # Safety
+    ///
+    /// The caller must ensure that:
+    /// * `raw` is a non-null, properly aligned pointer to a valid `FuzzTestCoverageDomainRegistry`.
+    /// * `(*raw).ctx` is a valid context pointer.
+    /// * The registry and its context remain valid for the duration of `CoverageDomainRegistry`'s usage
+    ///   (guaranteed by the engine until `FreeCtx` is called on the adapter).
+    pub unsafe fn from_raw(raw: *const engine_ffi::FuzzTestCoverageDomainRegistry) -> Self {
+        // SAFETY: Caller guarantees `raw` is a valid pointer to `FuzzTestCoverageDomainRegistry`.
+        let raw_registry = unsafe { *raw };
+        Self { raw: raw_registry }
+    }
+
+    /// Sets up SanitizerCoverage domains.
+    pub fn set_up_sancov_domains(&self) {
+        // SAFETY: The registry pointer is guaranteed to be valid by the framework.
+        unsafe { SanCovRuntimeSetUpCoverageDomains(&self.raw) };
+    }
+}
diff --git a/rust/fuzztest_macro/.rustfmt.toml b/rust/fuzztest_macro/.rustfmt.toml
new file mode 100644
index 0000000..33b356d
--- /dev/null
+++ b/rust/fuzztest_macro/.rustfmt.toml
@@ -0,0 +1,3 @@
+use_field_init_shorthand = true
+use_try_shorthand = true
+edition = "2021"
diff --git a/rust/fuzztest_macro/BUILD b/rust/fuzztest_macro/BUILD
new file mode 100644
index 0000000..13b6775
--- /dev/null
+++ b/rust/fuzztest_macro/BUILD
@@ -0,0 +1,41 @@
+load("@rules_rust//rust:defs.bzl", "rust_proc_macro", "rust_test")
+
+licenses(["notice"])
+
+rust_proc_macro(
+    name = "fuzztest_macro",
+    srcs = glob(
+        [
+            "src/**/*.rs",
+        ],
+        exclude = ["src/test_main.rs"],
+    ),
+    edition = "2024",
+    visibility = ["@com_google_fuzztest//rust:__subpackages__"],
+    deps = [
+        "@crate_index//:convert_case",  # v0_4
+        "@crate_index//:proc-macro2",
+        "@crate_index//:proc-macro-crate",
+        "@crate_index//:quote",  # v1
+        "@crate_index//:syn",  # v2
+    ],
+)
+
+rust_test(
+    name = "fuzztest_macro_test",
+    srcs = glob(
+        ["src/**/*.rs"],
+        exclude = ["src/lib.rs"],
+    ),
+    crate_root = "src/test_main.rs",
+    edition = "2024",
+    proc_macro_deps = [":fuzztest_macro"],
+    deps = [
+        "@crate_index//:googletest",
+        "@crate_index//:convert_case",  # v0_4
+        "@crate_index//:proc-macro2",
+        "@crate_index//:proc-macro-crate",
+        "@crate_index//:quote",  # v1
+        "@crate_index//:syn",  # v2
+    ],
+)
diff --git a/rust/fuzztest_macro/Cargo.toml b/rust/fuzztest_macro/Cargo.toml
new file mode 100644
index 0000000..4dfad0e
--- /dev/null
+++ b/rust/fuzztest_macro/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "fuzztest-macro"
+version = "0.1.0"
+edition = "2024"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+convert_case.workspace = true
+proc-macro2.workspace = true
+proc-macro-crate.workspace = true
+quote.workspace = true
+syn.workspace = true
+
+
+[dev-dependencies]
+googletest = "0.14.3"
diff --git a/rust/fuzztest_macro/src/helpers.rs b/rust/fuzztest_macro/src/helpers.rs
new file mode 100644
index 0000000..14578c9
--- /dev/null
+++ b/rust/fuzztest_macro/src/helpers.rs
@@ -0,0 +1,26 @@
+use proc_macro2::Span;
+use proc_macro2::TokenStream;
+use proc_macro_crate::FoundCrate;
+use quote::quote;
+use syn::Ident;
+
+mod fn_item_utils;
+mod fuzztest_domain;
+pub mod test_registration;
+
+#[derive(Debug, Clone)]
+struct TestFnArgument<'a> {
+    name: &'a syn::Ident,
+    ty: syn::Type,
+}
+
+fn import_fuzztest_crate() -> TokenStream {
+    match proc_macro_crate::crate_name("fuzztest") {
+        Ok(FoundCrate::Itself) => quote! { crate },
+        Ok(FoundCrate::Name(name)) => {
+            let ident = Ident::new(&name, Span::call_site());
+            quote! { #ident }
+        }
+        Err(_) => quote! { ::fuzztest },
+    }
+}
diff --git a/rust/fuzztest_macro/src/helpers/fn_item_utils.rs b/rust/fuzztest_macro/src/helpers/fn_item_utils.rs
new file mode 100644
index 0000000..0fd0f2c
--- /dev/null
+++ b/rust/fuzztest_macro/src/helpers/fn_item_utils.rs
@@ -0,0 +1,233 @@
+use syn::parse_quote;
+use syn::visit_mut::{self, VisitMut};
+use syn::BareFnArg;
+use syn::Error;
+use syn::FnArg;
+use syn::Pat;
+use syn::Signature;
+use syn::TypeBareFn;
+
+use super::TestFnArgument;
+
+struct LifetimeReplacer<'a> {
+    user_value_lifetime_generic: &'a syn::Lifetime,
+}
+
+impl<'a> VisitMut for LifetimeReplacer<'a> {
+    fn visit_lifetime_mut(&mut self, lifetime: &mut syn::Lifetime) {
+        // If the lifetime is `'static`, we don't want to replace it.
+        if lifetime.ident != "static" {
+            *lifetime = self.user_value_lifetime_generic.clone();
+        }
+        visit_mut::visit_lifetime_mut(self, lifetime);
+    }
+}
+
+/// Extracts the type of the arguments of a given function item (ie: a `syn::ItemFn`).
+pub fn extract_test_function_arguments<'a>(
+    fn_signature: &'a Signature,
+    user_value_lifetime_generic: &syn::Lifetime,
+) -> syn::Result<Vec<TestFnArgument<'a>>> {
+    fn_signature
+        .inputs
+        .iter()
+        .map(|arg| match arg {
+            FnArg::Receiver(_) => {
+                Err(Error::new_spanned(arg, "Receiver is not supported in property functions."))
+            }
+            FnArg::Typed(pat_type) => match pat_type.pat.as_ref() {
+                Pat::Ident(pat_ident) => {
+                    let mut ty = pat_type.ty.as_ref().clone();
+                    let mut lifetime_replacer = LifetimeReplacer { user_value_lifetime_generic };
+                    lifetime_replacer.visit_type_mut(&mut ty);
+                    Ok(TestFnArgument { name: &pat_ident.ident, ty })
+                }
+                pat => Err(Error::new_spanned(pat, "Expected an identifier")),
+            },
+        })
+        .collect::<syn::Result<Vec<_>>>()
+}
+
+/// Extract a bare function pointer type (`syn::TypeBareFn``) from a given
+/// signature (`syn::Signature`)
+///
+/// For example, passing in a `syn::Signature` representing the function
+/// `fn test_function(mut a: i32, b: std::string::String)` would yield the
+/// following bare function pointer type `fn(i32, std::string::String)`.
+///
+/// Example usage:
+/// ```markdown
+/// ```
+/// # use syn::parse_quote;
+///
+/// let signature = parse_quote! {
+///   fn test_function(mut a: i32, b: std::string::String)
+/// };
+///
+/// assert_eq!(fn_sig_to_bare_type(&signature), parse_quote!(fn(i32, std::string::String)));
+/// ```
+/// ```
+///
+pub fn fn_sig_to_bare_type(fn_sig: &Signature) -> syn::Result<TypeBareFn> {
+    let generics = &fn_sig.generics;
+    if generics.type_params().count() > 0 || generics.const_params().count() > 0 {
+        return Err(Error::new_spanned(
+            generics,
+            "Property function should not have any Type or Const generics",
+        ));
+    }
+
+    let bare_input_args = fn_sig
+        .inputs
+        .iter()
+        .map(|arg| match arg {
+            FnArg::Receiver(_) => {
+                Err(Error::new_spanned(arg, "Receiver is not supported in property functions."))
+            }
+            FnArg::Typed(pat_type) => Ok(BareFnArg {
+                attrs: pat_type.attrs.clone(),
+                name: None,
+                ty: pat_type.ty.as_ref().clone(),
+            }),
+        })
+        .collect::<syn::Result<Vec<_>>>()?;
+    let fn_lifetime_generics = generics.lifetimes().collect::<Vec<_>>();
+    let unsafety = &fn_sig.unsafety;
+    let abi = &fn_sig.abi;
+    let variadic = &fn_sig.variadic;
+    let output = &fn_sig.output;
+    if fn_lifetime_generics.is_empty() {
+        Ok(parse_quote! {
+          #unsafety #abi fn (#(#bare_input_args),* #variadic) #output
+        })
+    } else {
+        Ok(parse_quote! {
+          for< #(#fn_lifetime_generics),* > #unsafety #abi fn (#(#bare_input_args),* #variadic) #output
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use googletest::prelude::*;
+
+    #[googletest::test]
+    fn test_extract_test_function_arguments_succeeds() {
+        let fn_item: Signature = syn::parse_quote! {
+            fn test_function(mut a: i32, b: std::string::String)
+        };
+        let user_value_lifetime_generic = parse_quote!('user);
+
+        let test_fn_arguments =
+            extract_test_function_arguments(&fn_item, &user_value_lifetime_generic);
+
+        expect_that!(
+            test_fn_arguments,
+            ok(elements_are![
+                matches_pattern!(TestFnArgument {
+                    name: eq(&&quote::format_ident!("a")),
+                    ty: eq(&syn::parse_quote! { i32 }),
+                }),
+                matches_pattern!(TestFnArgument {
+                    name: eq(&&quote::format_ident!("b")),
+                    ty: eq(&syn::parse_quote! { std::string::String }),
+                })
+            ])
+        );
+    }
+
+    #[googletest::test]
+    fn test_extract_test_function_arguments_with_lifetimes_succeeds() {
+        let fn_item: Signature = syn::parse_quote! {
+            fn test_function<'a, 'b>(mut a: i32, b: &'a str, c: &'b Vec<&'static u8>)
+        };
+        let user_value_lifetime_generic = parse_quote!('user);
+
+        let test_fn_arguments =
+            extract_test_function_arguments(&fn_item, &user_value_lifetime_generic);
+
+        expect_that!(
+            test_fn_arguments,
+            ok(elements_are![
+                matches_pattern!(TestFnArgument {
+                    name: eq(&&quote::format_ident!("a")),
+                    ty: eq(&syn::parse_quote! { i32 }),
+                }),
+                matches_pattern!(TestFnArgument {
+                    name: eq(&&quote::format_ident!("b")),
+                    ty: eq(&syn::parse_quote! { &'user str }),
+                }),
+                matches_pattern!(TestFnArgument {
+                    name: eq(&&quote::format_ident!("c")),
+                    ty: eq(&syn::parse_quote! { &'user Vec<&'static u8> }),
+                })
+            ])
+        );
+    }
+
+    #[googletest::test]
+    fn test_extract_test_function_arguments_fails_with_non_ident_arg() {
+        let fn_item: Signature = syn::parse_quote! {
+            fn test_function(
+              MyStruct { a }: MyStruct, b: std::string::String)
+        };
+        let user_value_lifetime_generic = parse_quote!('user);
+
+        let test_fn_arguments =
+            extract_test_function_arguments(&fn_item, &user_value_lifetime_generic);
+
+        expect_that!(
+            test_fn_arguments,
+            err(displays_as(contains_substring("Expected an identifier")))
+        );
+    }
+
+    #[googletest::test]
+    fn test_extract_test_function_arguments_fails_with_receiver_arg() {
+        let fn_item: Signature = syn::parse_quote! {
+            fn test_function(&self, b: std::string::String)
+        };
+        let user_value_lifetime_generic = parse_quote!('user);
+
+        let test_fn_arguments =
+            extract_test_function_arguments(&fn_item, &user_value_lifetime_generic);
+
+        expect_that!(
+            test_fn_arguments,
+            err(displays_as(contains_substring(
+                "Receiver is not supported in property functions."
+            )))
+        );
+    }
+
+    #[googletest::test]
+    fn test_convert_fn_sig_to_bare_type_fn_succeeds() {
+        expect_that!(
+            fn_sig_to_bare_type(&parse_quote! {
+              fn test_function(a: i32, b: std::string::String) -> bool
+            }),
+            ok(eq(&parse_quote! {fn (i32, std::string::String) -> bool }))
+        )
+    }
+
+    #[googletest::test]
+    fn test_convert_fn_sig_with_no_return_type_to_bare_type_fn_succeeds() {
+        expect_that!(
+            fn_sig_to_bare_type(&parse_quote! {
+              fn test_function(a: i32, b: std::string::String)
+            }),
+            ok(eq(&parse_quote! {fn (i32, std::string::String) }))
+        )
+    }
+
+    #[googletest::test]
+    fn test_convert_fn_sig_with_lifetimes_to_bare_type_fn_succeeds() {
+        expect_that!(
+            fn_sig_to_bare_type(&parse_quote! {
+              fn test_function<'a, 'b>(a: std::vec::Vec<&'a i32>, b: Test<'b>)
+            }),
+            ok(eq(&parse_quote! {for<'a, 'b> fn (std::vec::Vec<&'a i32>, Test<'b>) }))
+        )
+    }
+}
diff --git a/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs b/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs
new file mode 100644
index 0000000..31e334d
--- /dev/null
+++ b/rust/fuzztest_macro/src/helpers/fuzztest_domain.rs
@@ -0,0 +1,162 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::parse_quote;
+use syn::Generics;
+use syn::Ident;
+
+use super::import_fuzztest_crate;
+use super::TestFnArgument;
+
+/// Generates a wrapper domain that will contain all domains of the test
+/// function arguments.
+pub fn generate_fuzztest_domain<'a, 'b: 'a>(
+    domain_struct_name: &Ident,
+    test_fn_args: impl IntoIterator<Item = &'a TestFnArgument<'b>>,
+    user_value_lifetime_generic: &syn::Lifetime,
+) -> (TokenStream, Vec<Ident>) {
+    let crate_name = import_fuzztest_crate();
+    let test_fn_args = test_fn_args.into_iter().collect::<Vec<_>>();
+
+    let domain_generics =
+        (0..test_fn_args.len()).map(|idx| quote::format_ident!("T{idx}")).collect::<Vec<_>>();
+
+    let corpus_domain_generics = domain_generics
+        .iter()
+        .map(|generic| parse_quote!(#generic::CorpusValue))
+        .collect::<Vec<syn::Type>>();
+    let user_value_domain_generics = domain_generics
+        .iter()
+        .map(|generic| parse_quote!(#generic::UserValue<#user_value_lifetime_generic>))
+        .collect::<Vec<syn::Type>>();
+    let mut generics: Generics = parse_quote! { < #(#domain_generics),* > };
+
+    let test_fn_args_with_generics =
+        test_fn_args.into_iter().zip(generics.type_params().cloned()).collect::<Vec<_>>();
+
+    let mut field_names = vec![];
+    let mut domain_field_types = vec![];
+
+    let where_clauses = generics.make_where_clause();
+    for (TestFnArgument { ty, name }, syn::TypeParam { ident: domain_gen, .. }) in
+        &test_fn_args_with_generics
+    {
+        where_clauses.predicates.push(
+          parse_quote! {
+            for <#user_value_lifetime_generic> #domain_gen: #crate_name::domains::Domain<UserValue<#user_value_lifetime_generic> = #ty >
+          });
+        where_clauses.predicates.push(parse_quote! { #domain_gen::CorpusValue: #crate_name::serde::Serialize + #crate_name::serde::de::DeserializeOwned + ::std::clone::Clone });
+        field_names.push((*name).clone());
+        domain_field_types.push(domain_gen);
+    }
+
+    let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+    let serde_crate_path = format!("{}", quote!(#crate_name::serde));
+
+    let domain_definition_tokens = quote! {
+      #[derive(#crate_name::serde::Serialize, #crate_name::serde::Deserialize, ::std::fmt::Debug, ::std::clone::Clone)]
+      #[serde(crate = #serde_crate_path)]
+      struct #domain_struct_name #ty_generics {
+        #(#field_names : #domain_field_types),*
+      }
+
+      impl #impl_generics #crate_name::domains::Domain for #domain_struct_name #ty_generics #where_clause {
+        type UserValue<#user_value_lifetime_generic> = #domain_struct_name <#(#user_value_domain_generics),*>;
+        type CorpusValue = #domain_struct_name <#(#corpus_domain_generics),*>;
+
+        fn init(&self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+          Ok(#domain_struct_name {
+            #(#field_names: self.#field_names.init(rng)?),*
+          })
+        }
+
+        fn mutate(
+            &self,
+            val: &mut Self::CorpusValue,
+            rng: &mut dyn ::fuzztest::reexports::rand::Rng,
+            only_shrink: bool,
+        ) -> ::fuzztest::reexports::anyhow::Result<()> {
+          #( self.#field_names.mutate(&mut val.#field_names, rng, only_shrink)?; )*
+          Ok(())
+        }
+
+        fn get_user_value<'a>(&self, corpus_value: &'a Self::CorpusValue) -> ::fuzztest::reexports::anyhow::Result<Self::UserValue<'a>> {
+          Ok(#domain_struct_name {
+            #(#field_names: self.#field_names.get_user_value(&corpus_value.#field_names)?),*
+          })
+        }
+      }
+    };
+    (domain_definition_tokens, field_names)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use googletest::prelude::*;
+
+    #[googletest::test]
+    fn test_generate_fuzztest_domain() {
+        let (domain_definition_tokens, field_names) = generate_fuzztest_domain(
+            &quote::format_ident!("__FuzzTestTestFuzzStateWrapper"),
+            &[
+                TestFnArgument {
+                    name: &quote::format_ident!("a"),
+                    ty: parse_quote!(&'user Vec<&'user i32>),
+                },
+                TestFnArgument {
+                    name: &quote::format_ident!("b"),
+                    ty: parse_quote!(std::string::String),
+                },
+            ],
+            &parse_quote!('user),
+        );
+        expect_that!(
+            field_names,
+            elements_are![eq(&quote::format_ident!("a")), eq(&quote::format_ident!("b"))]
+        );
+        expect_that!(domain_definition_tokens.to_string(), eq( &quote! {
+            #[derive(::fuzztest::serde::Serialize, ::fuzztest::serde::Deserialize, ::std::fmt::Debug, ::std::clone::Clone)]
+            #[serde(crate = ":: fuzztest :: serde")]
+            struct __FuzzTestTestFuzzStateWrapper<T0, T1> {
+              a: T0,
+              b: T1
+            }
+
+            impl<T0, T1> ::fuzztest::domains::Domain for __FuzzTestTestFuzzStateWrapper<T0, T1>
+            where for < 'user > T0: ::fuzztest::domains::Domain<UserValue< 'user > = &'user Vec<&'user i32> >,
+                  T0::CorpusValue: ::fuzztest::serde::Serialize + ::fuzztest::serde::de::DeserializeOwned + ::std::clone::Clone,
+                  for < 'user > T1: ::fuzztest::domains::Domain<UserValue< 'user > = std::string::String>,
+                  T1::CorpusValue: ::fuzztest::serde::Serialize + ::fuzztest::serde::de::DeserializeOwned + ::std::clone::Clone {
+              type UserValue<'user> = __FuzzTestTestFuzzStateWrapper<T0::UserValue<'user>, T1::UserValue<'user> >;
+              type CorpusValue = __FuzzTestTestFuzzStateWrapper<T0::CorpusValue, T1::CorpusValue>;
+
+              fn init(&self, rng: &mut dyn ::fuzztest::reexports::rand::Rng) -> ::fuzztest::reexports::anyhow::Result<Self::CorpusValue> {
+                Ok(__FuzzTestTestFuzzStateWrapper {
+                  a: self.a.init(rng)?,
+                  b: self.b.init(rng)?
+                })
+              }
+
+              fn mutate(
+                  &self,
+                  val: &mut Self::CorpusValue,
+                  rng: &mut dyn ::fuzztest::reexports::rand::Rng,
+                  only_shrink: bool,
+              ) -> ::fuzztest::reexports::anyhow::Result<()> {
+                self.a.mutate(&mut val.a, rng, only_shrink)?;
+                self.b.mutate(&mut val.b, rng, only_shrink)?;
+                Ok(())
+              }
+
+              fn get_user_value<'a>(&self, corpus_value: &'a Self::CorpusValue) -> ::fuzztest::reexports::anyhow::Result<Self::UserValue<'a>> {
+                Ok(__FuzzTestTestFuzzStateWrapper {
+                  a: self.a.get_user_value(&corpus_value.a)?,
+                  b: self.b.get_user_value(&corpus_value.b)?
+                })
+              }
+            }
+          }
+          .to_string())
+      );
+    }
+}
diff --git a/rust/fuzztest_macro/src/helpers/test_registration.rs b/rust/fuzztest_macro/src/helpers/test_registration.rs
new file mode 100644
index 0000000..d44614c
--- /dev/null
+++ b/rust/fuzztest_macro/src/helpers/test_registration.rs
@@ -0,0 +1,378 @@
+use convert_case::Case;
+use convert_case::Casing;
+use proc_macro2::Span;
+use proc_macro2::TokenStream;
+use quote::quote;
+use syn::parse_quote;
+use syn::Expr;
+use syn::Generics;
+use syn::Ident;
+use syn::Lifetime;
+use syn::Signature;
+
+use super::fn_item_utils::extract_test_function_arguments;
+use super::fn_item_utils::fn_sig_to_bare_type;
+use super::fuzztest_domain::generate_fuzztest_domain;
+use super::import_fuzztest_crate;
+use super::TestFnArgument;
+
+const USER_VALUE_LIFETIME_GENERIC_NAME: &str = "'user";
+
+#[derive(Clone, Debug)]
+pub struct FuzzTestObjectDefinitionAndFactory {
+    pub fuzztest_object_factory_name: Ident,
+    pub fuzztest_object_tokenstream: TokenStream,
+}
+
+#[derive(Clone, Debug)]
+pub struct GTestDefinition {
+    pub gtest_tokens: TokenStream,
+}
+
+/// A context struct holding the pre-computed information and token streams required
+/// to generate the fuzz test registration, struct definitions, and integration with the test framework.
+///
+/// This context is created once per property function.
+pub struct FuzzTestRegistrationCtx<'a> {
+    test_fn_signature: &'a Signature,
+    test_fn_ident: &'a Ident,
+    prop_fn_ident: Ident,
+    test_fn_args: Vec<TestFnArgument<'a>>,
+    crate_name: TokenStream,
+    fuzz_test_domain_definition: TokenStream,
+    fuzz_test_domain_field_names: Vec<Ident>,
+    fuzz_test_struct_instance_tokens: TokenStream,
+    fuzz_test_struct_factory_fn_name: Ident,
+}
+
+impl<'a> FuzzTestRegistrationCtx<'a> {
+    /// Creates a new registration context from a property function signature and its domain constructors.
+    ///
+    /// This method analyzes the inputs, derives necessary identifiers and lifetime generics, and
+    /// pre-computes the tokenstream for the fuzz test struct instance.
+    pub fn new(
+        test_fn_signature: &'a Signature,
+        domain_ctors: impl IntoIterator<Item = &'a Expr>,
+    ) -> syn::Result<Self> {
+        let user_value_lifetime_generic =
+            Lifetime::new(USER_VALUE_LIFETIME_GENERIC_NAME, Span::call_site());
+
+        let test_fn_args =
+            extract_test_function_arguments(test_fn_signature, &user_value_lifetime_generic)?;
+        if test_fn_args.is_empty() {
+            return Err(syn::Error::new_spanned(
+                test_fn_signature,
+                "fuzztest requires at least one argument for the property function",
+            ));
+        }
+
+        let test_fn_generics = &test_fn_signature.generics;
+        if test_fn_generics.type_params().count() > 0 || test_fn_generics.const_params().count() > 0
+        {
+            return Err(syn::Error::new_spanned(
+                test_fn_generics,
+                "Property function should not have any Type or Const generics",
+            ));
+        }
+
+        let test_fn_ident = &test_fn_signature.ident;
+        let prop_fn_ident = quote::format_ident!("__property_fn__{}", test_fn_ident);
+        let domain_ctors = domain_ctors.into_iter().collect::<Vec<_>>();
+        let fuzz_test_struct_name =
+            quote::format_ident!("__FuzzTest{}", test_fn_ident.to_string().to_case(Case::Pascal));
+        let crate_name = import_fuzztest_crate();
+
+        let domain_struct_name = quote::format_ident!(
+            "__FuzzTest{}StateWrapper",
+            test_fn_ident.to_string().to_case(Case::Pascal)
+        );
+
+        let (fuzz_test_domain_definition, fuzz_test_domain_field_names) = generate_fuzztest_domain(
+            &domain_struct_name,
+            &test_fn_args,
+            &user_value_lifetime_generic,
+        );
+
+        let fuzz_test_struct_instance_tokens = quote!(
+          #fuzz_test_struct_name {
+              domain: #domain_struct_name {
+                  #(#fuzz_test_domain_field_names: #domain_ctors),*
+              },
+              test_fn: #prop_fn_ident
+          }
+        );
+
+        let fuzz_test_struct_factory_fn_name =
+            quote::format_ident!("{}_factory", fuzz_test_struct_name);
+
+        Ok(Self {
+            test_fn_signature,
+            test_fn_ident,
+            prop_fn_ident,
+            test_fn_args,
+            crate_name,
+            fuzz_test_domain_definition,
+            fuzz_test_domain_field_names,
+            fuzz_test_struct_instance_tokens,
+            fuzz_test_struct_factory_fn_name,
+        })
+    }
+
+    pub fn prop_fn_ident(&self) -> &Ident {
+        &self.prop_fn_ident
+    }
+
+    /// Generates a GoogleTest-compatible test function that wraps the fuzz test.
+    ///
+    /// This allows the fuzz test to be executed as a regular tests.
+    pub fn generate_gtest(&self) -> syn::Result<GTestDefinition> {
+        let gtest_name = &self.test_fn_ident;
+        let crate_name = &self.crate_name;
+        let test_fn_name = self.test_fn_ident.to_string();
+        let fuzz_test_factory = &self.fuzz_test_struct_factory_fn_name;
+
+        let tokens = quote!(
+            #[::googletest::prelude::gtest]
+            fn #gtest_name() {
+                // Note: In this setup, `module_path!()` returns a path that starts with the crate name
+                // (e.g., `crate_name::module::path`). We want to strip this prefix to make the
+                // test name similar to standard `libtest` paths.
+                let full_test_name = concat!(module_path!(), "::", #test_fn_name);
+                let test_name = full_test_name
+                    .split_once("::")
+                    .expect("Crate name is always the first path segment")
+                    .1;
+                let manager = #crate_name::worker::RustFuzzTestAdapterManager {
+                    test_name,
+                    fuzz_test_factory: #fuzz_test_factory,
+                };
+                #crate_name::worker::process(manager);
+            }
+        );
+
+        Ok(GTestDefinition { gtest_tokens: tokens })
+    }
+
+    /// Generates the test `struct` that will contain the state of the test:
+    ///  - the domain of the property function inputs
+    ///  - the property function itself
+    ///
+    /// The generated test `struct` object will implement the FuzzTest trait.
+    pub fn generate_test_registration(&self) -> syn::Result<FuzzTestObjectDefinitionAndFactory> {
+        let crate_name = &self.crate_name;
+        let user_value_lifetime_generic =
+            Lifetime::new(USER_VALUE_LIFETIME_GENERIC_NAME, Span::call_site());
+        let test_fn_args = &self.test_fn_args;
+        let test_fn_args_len = test_fn_args.len();
+
+        let test_fn_type = fn_sig_to_bare_type(self.test_fn_signature)?;
+
+        let test_fn_ident = self.test_fn_ident;
+        let fuzz_test_struct_name =
+            quote::format_ident!("__FuzzTest{}", test_fn_ident.to_string().to_case(Case::Pascal));
+        let domain_struct_name = quote::format_ident!(
+            "__FuzzTest{}StateWrapper",
+            test_fn_ident.to_string().to_case(Case::Pascal)
+        );
+        let test_fn_name = test_fn_ident.to_string();
+        let fuzz_test_struct_factory_fn_name = &self.fuzz_test_struct_factory_fn_name;
+
+        let domain_generics =
+            (0..test_fn_args_len).map(|idx| quote::format_ident!("T{idx}")).collect::<Vec<_>>();
+        let corpus_generics = domain_generics
+            .iter()
+            .map(|generic| parse_quote!(#generic::CorpusValue))
+            .collect::<Vec<syn::Type>>();
+
+        let mut generics: Generics = parse_quote! { < #(#domain_generics),* > };
+
+        let test_fn_args_with_generics = test_fn_args
+            .iter()
+            .zip(generics.type_params().cloned())
+            .zip(corpus_generics.iter())
+            .collect::<Vec<_>>();
+
+        let where_clauses = generics.make_where_clause();
+        for ((TestFnArgument { ty, .. }, syn::TypeParam { ident: domain_gen, .. }), corpus_gen) in
+            &test_fn_args_with_generics
+        {
+            where_clauses.predicates.push(
+          parse_quote! {
+            for <#user_value_lifetime_generic> #domain_gen: #crate_name::domains::Domain<UserValue<#user_value_lifetime_generic> = #ty >
+        });
+            where_clauses.predicates.push(parse_quote! { #corpus_gen: 'static });
+        }
+
+        let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+        let fuzztest_instance = &self.fuzz_test_struct_instance_tokens;
+        let fuzz_test_domain_field_names = &self.fuzz_test_domain_field_names;
+        let fuzz_test_domain_definition = &self.fuzz_test_domain_definition;
+
+        let fuzztest_struct_definition_and_factory = quote! {
+          #fuzz_test_domain_definition
+
+          struct #fuzz_test_struct_name #generics {
+            domain: #domain_struct_name #generics,
+            test_fn: #test_fn_type
+          }
+
+          impl #impl_generics #crate_name::internal::FuzzTest for #fuzz_test_struct_name #ty_generics #where_clause {
+              fn name(&self) -> &'static str {
+                  #test_fn_name
+              }
+              fn activate(&mut self) {
+                  todo!("Not implemented!")
+              }
+              fn mutate(&mut self) {
+                  todo!("Not implemented!")
+              }
+              fn execute<'a>(&self, args: &'a #crate_name::domains::GenericCorpusValue) -> bool {
+                  use #crate_name::domains::Domain;
+
+                  let wrapper = args
+                                .downcast_ref::<#domain_struct_name<#(#corpus_generics),*>>()
+                                .expect("Attempt to recover user value before testing failed.");
+
+                  let user_value = self.domain.get_user_value(wrapper).expect("Failed to get user value from corpus value");
+
+                  let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| (self.test_fn)(#(user_value.#fuzz_test_domain_field_names),* ) ));
+
+                  result.is_ok()
+              }
+              fn print_finding_report(&self) {
+                  todo!("Not implemented!")
+              }
+              fn domains(&self) -> &dyn #crate_name::domains::GenericDomain {
+                &self.domain
+              }
+          }
+
+          fn #fuzz_test_struct_factory_fn_name() -> #crate_name::internal::BoxedFuzzTest {
+            ::std::boxed::Box::new(#fuzztest_instance)
+          }
+        };
+
+        Ok(FuzzTestObjectDefinitionAndFactory {
+            fuzztest_object_factory_name: fuzz_test_struct_factory_fn_name.clone(),
+            fuzztest_object_tokenstream: fuzztest_struct_definition_and_factory,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use googletest::matchers;
+    use googletest::prelude::*;
+
+    #[googletest::test]
+    fn test_generate_test_registration() {
+        let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
+        let expr1: Expr =
+            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+        let expr2: Expr =
+            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
+        let context = FuzzTestRegistrationCtx::new(&sig, [&expr1, &expr2]).unwrap();
+        let FuzzTestObjectDefinitionAndFactory {
+            fuzztest_object_factory_name,
+            fuzztest_object_tokenstream,
+        } = context.generate_test_registration().unwrap();
+        expect_that!(
+            fuzztest_object_factory_name,
+            eq(&quote::format_ident!("__FuzzTestTestFuzz_factory"))
+        );
+        expect_that!(
+          fuzztest_object_tokenstream.to_string(), ends_with( quote! {
+              struct __FuzzTestTestFuzz<T0, T1> {
+                domain: __FuzzTestTestFuzzStateWrapper<T0, T1>,
+                test_fn: fn(i32, std::string::String)
+              }
+
+              impl<T0, T1> ::fuzztest::internal::FuzzTest for __FuzzTestTestFuzz<T0, T1>
+              where for <'user> T0: ::fuzztest::domains::Domain<UserValue<'user> = i32>,
+                    T0::CorpusValue: 'static,
+                    for <'user> T1: ::fuzztest::domains::Domain<UserValue<'user> = std::string::String>,
+                    T1::CorpusValue: 'static {
+                  fn name(&self) -> &'static str {
+                    "test_fuzz"
+                  }
+                  fn activate(&mut self) {
+                    todo!("Not implemented!")
+                  }
+                  fn mutate(&mut self) {
+                    todo!("Not implemented!")
+                  }
+                  fn execute<'a>(&self, args: &'a ::fuzztest::domains::GenericCorpusValue) -> bool {
+                    use ::fuzztest::domains::Domain;
+
+                    let wrapper = args
+                            .downcast_ref::<__FuzzTestTestFuzzStateWrapper<T0::CorpusValue, T1::CorpusValue>>()
+                            .expect("Attempt to recover user value before testing failed.");
+
+                    let user_value = self.domain.get_user_value(wrapper).expect("Failed to get user value from corpus value");
+                    // Safety: Data is not reused after the test.
+                    let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| (self.test_fn)(user_value.a, user_value.b) ));
+
+                    result.is_ok()
+                  }
+                  fn print_finding_report(&self) {
+                    todo!("Not implemented!")
+                  }
+                  fn domains(&self) -> &dyn ::fuzztest::domains::GenericDomain {
+                    &self.domain
+                  }
+              }
+
+              fn __FuzzTestTestFuzz_factory() -> ::fuzztest::internal::BoxedFuzzTest {
+                ::std::boxed::Box::new(__FuzzTestTestFuzz {
+                  domain: __FuzzTestTestFuzzStateWrapper {
+                    a: ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default(),
+                    b: ::fuzztest::domains::arbitrary::Arbitrary::<String>::default()
+                  },
+                  test_fn: __property_fn__test_fuzz
+                })
+              }
+            }
+            .to_string())
+        );
+    }
+
+    #[googletest::test]
+    fn test_generate_gtest() {
+        let sig: Signature = parse_quote! { fn test_fuzz(a: i32, b: std::string::String) };
+        let expr1: Expr =
+            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<i32>::default() };
+        let expr2: Expr =
+            parse_quote! { ::fuzztest::domains::arbitrary::Arbitrary::<String>::default() };
+        let context = FuzzTestRegistrationCtx::new(&sig, [&expr1, &expr2]).unwrap();
+        let GTestDefinition { gtest_tokens } = context.generate_gtest().unwrap();
+
+        // test that the gtest was generated
+        expect_that!(
+            gtest_tokens.to_string(),
+            matchers::contains_substring(
+                quote! {
+                    #[::googletest::prelude::gtest]
+                    fn test_fuzz()
+                }
+                .to_string()
+            )
+        );
+
+        // test that the test_name is the test path
+        expect_that!(
+            gtest_tokens.to_string(),
+            matchers::contains_substring(
+                quote! {
+                    let full_test_name = concat!(module_path!(), "::", "test_fuzz");
+                    let test_name = full_test_name
+                        .split_once("::")
+                        .expect("Crate name is always the first path segment")
+                        .1;
+                }
+                .to_string()
+            )
+        )
+    }
+}
diff --git a/rust/fuzztest_macro/src/lib.rs b/rust/fuzztest_macro/src/lib.rs
new file mode 100644
index 0000000..19450ea
--- /dev/null
+++ b/rust/fuzztest_macro/src/lib.rs
@@ -0,0 +1,126 @@
+/// Modules here cannot be public (ie: `pub`) because a proc-macro crate cannot export anything else
+/// other than a proc-macro. That is to say, a function tagged with `#[proc_macro]`,
+/// `#[proc_macro_attribute]`, `#[proc_macro_derive]`
+mod helpers;
+
+use proc_macro::TokenStream;
+
+use quote::quote;
+use syn::parse::{Parse, ParseStream, Parser};
+use syn::{parse_macro_input, Item};
+
+use helpers::test_registration::FuzzTestObjectDefinitionAndFactory;
+use helpers::test_registration::FuzzTestRegistrationCtx;
+use helpers::test_registration::GTestDefinition;
+
+#[derive(Debug)]
+struct FuzzTestArg {
+    _ident: syn::Ident,
+    _eq_token: syn::Token![=],
+    domain_ty: syn::Expr,
+}
+
+impl Parse for FuzzTestArg {
+    fn parse(input: ParseStream) -> syn::Result<Self> {
+        Ok(Self { _ident: input.parse()?, _eq_token: input.parse()?, domain_ty: input.parse()? })
+    }
+}
+
+/// The `fuzztest` macro is used to generate and register a fuzz test object to be used by a fuzz
+/// testing engine.
+///
+/// The macro takes a list of arguments, where each argument is a domain object used to generate
+/// values for the property function inputs.
+///
+/// Example usage:
+/// ```markdown
+/// ```
+/// # use fuzztest::fuzztest;
+/// # use fuzztest::domains::arbitrary::Arbitrary;
+/// # use fuzztest::domains::range::InRange;
+///
+/// #[fuzztest(a = Arbitrary::<i32>::default(), b = InRange::new(0, 10))]
+/// fn fuzz_test_function(a: i32, b: i32) {
+///     assert_eq!(a, b);
+/// }
+/// ```
+/// ```
+///
+#[proc_macro_attribute]
+pub fn fuzztest(args: TokenStream, input: TokenStream) -> TokenStream {
+    let item = parse_macro_input!(input as Item);
+
+    let syn::Item::Fn(mut test_fn) = item else {
+        return syn::Error::new_spanned(item, "not a function").into_compile_error().into();
+    };
+
+    let original_ident = test_fn.sig.ident.clone();
+    let fuzztest_name = original_ident.to_string();
+
+    // TODO(mathuxny-73): Support the case where there are no arguments. Probably we should return an error
+    //  in this case as it may not make sense to have a FuzzTest without input.
+    let args =
+        syn::punctuated::Punctuated::<FuzzTestArg, syn::Token![,]>::parse_terminated.parse(args);
+
+    let args = match args {
+        Ok(args) => args,
+        Err(e) => return e.into_compile_error().into(),
+    };
+
+    let domain_ctors = args.iter().map(|arg| &arg.domain_ty);
+
+    let fuzztest_registration_context =
+        match FuzzTestRegistrationCtx::new(&test_fn.sig, domain_ctors) {
+            Ok(fuzztest_registration_context) => fuzztest_registration_context,
+            Err(e) => return e.into_compile_error().into(),
+        };
+
+    let FuzzTestObjectDefinitionAndFactory {
+        fuzztest_object_factory_name,
+        fuzztest_object_tokenstream,
+    } = match fuzztest_registration_context.generate_test_registration() {
+        Ok(fuzztest_object) => fuzztest_object,
+        Err(e) => return e.into_compile_error().into(),
+    };
+
+    let GTestDefinition { gtest_tokens } = match fuzztest_registration_context.generate_gtest() {
+        Ok(gtest_tokens) => gtest_tokens,
+        Err(e) => return e.into_compile_error().into(),
+    };
+
+    test_fn.sig.ident = fuzztest_registration_context.prop_fn_ident().clone();
+
+    let fuzztest_mod_name = quote::format_ident!("__fuzztest_mod__{}", original_ident);
+
+    // TODO(mathuxny-73): Extract the current module path from the invocation of the macro
+    //   (ie: from `item.attrs`)
+    let tokens = quote! {
+        #[allow(non_snake_case)]
+        mod #fuzztest_mod_name {
+            use super::*;
+
+            #test_fn
+
+            #fuzztest_object_tokenstream
+
+            const _: () = {
+                static FUZZTEST_INFO: ::fuzztest::internal::FuzzTestInfo =
+                ::fuzztest::internal::FuzzTestInfo {
+                    name: #fuzztest_name,
+                    file: file!(),
+                    line: line!(),
+                };
+
+                ::fuzztest::reexports::inventory::submit! {
+                ::fuzztest::internal::FuzzTestRegistration {
+                    info: &FUZZTEST_INFO,
+                    factory: #fuzztest_object_factory_name
+                }
+                }
+            };
+
+            #gtest_tokens
+        }
+    };
+    tokens.into()
+}
diff --git a/rust/fuzztest_macro/src/test_main.rs b/rust/fuzztest_macro/src/test_main.rs
new file mode 100644
index 0000000..f01ede3
--- /dev/null
+++ b/rust/fuzztest_macro/src/test_main.rs
@@ -0,0 +1,4 @@
+// This file exists only as a workaround. It serves as the crate root for the `fuzztest_macro_test`
+// BUILD target.
+// This file should not be included in the `fuzztest_macro` crate.
+mod helpers;
diff --git a/rust/rust-toolchain.toml b/rust/rust-toolchain.toml
new file mode 100644
index 0000000..0c3034f
--- /dev/null
+++ b/rust/rust-toolchain.toml
@@ -0,0 +1,9 @@
+# This file is used to configure the Rust toolchain for FuzzTest.
+#
+# The channel is set to nightly as the fuzztest crate makes use of the compiler
+# sanitizers, which are not yet part of the stable Rust toolchain.
+# See https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html
+#
+# See https://rust-lang.github.io/rustup/concepts/toolchains.html
+[toolchain]
+channel = "nightly"
diff --git a/rust/src/crash_handler.rs b/rust/src/crash_handler.rs
new file mode 100644
index 0000000..5dddf70
--- /dev/null
+++ b/rust/src/crash_handler.rs
@@ -0,0 +1,38 @@
+#[cfg(any(sanitize = "address", sanitize = "memory"))]
+mod callbacks {
+    use std::ffi::{c_char, CStr};
+
+    unsafe extern "C" {
+        pub safe fn __sanitizer_set_death_callback(callback: Option<extern "C" fn()>);
+
+        pub safe fn __asan_get_report_description() -> *const c_char;
+    }
+
+    pub extern "C" fn sanitizer_death_callback() {
+        use crate::worker;
+
+        let (description, signature) = if cfg!(sanitize = "address") {
+            let char_ptr = __asan_get_report_description();
+            // Safety: `ptr` points to a valid null terminated string.
+            let signature_cstr = unsafe { CStr::from_ptr(char_ptr) };
+            (
+                "Property function ran but address sanitizer caught a bug",
+                signature_cstr.to_str().unwrap_or("ASan crash"),
+            )
+        } else {
+            ("Property function ran but a sanitizer caught a bug", "Sanitizer crash")
+        };
+        worker::try_emit_finding(description, signature);
+    }
+}
+
+/// Be able to emit failures before exiting fully from the process for non-unwinding panics and/or
+/// unrecoverable crashes.
+pub fn register_crash_handler() {
+    // TODO(yamilmorales): Consider allowing more sanitizers here, and find some other way to
+    // recognize sanitizers if this feature is not stabilized by the time we need to support Cargo.
+    #[cfg(any(sanitize = "address", sanitize = "memory"))]
+    {
+        callbacks::__sanitizer_set_death_callback(Some(callbacks::sanitizer_death_callback));
+    }
+}
diff --git a/rust/src/domains.rs b/rust/src/domains.rs
new file mode 100644
index 0000000..9180d03
--- /dev/null
+++ b/rust/src/domains.rs
@@ -0,0 +1,230 @@
+pub mod arbitrary;
+pub mod range;
+pub mod tuple_of;
+pub mod utility;
+
+use anyhow;
+use anyhow::Context;
+
+use std::any::Any;
+
+pub trait CloneAny: Any {
+    fn clone_box(&self) -> Box<dyn CloneAny>;
+    fn as_any(&self) -> &dyn Any;
+    fn as_mut_any(&mut self) -> &mut dyn Any;
+}
+
+impl dyn CloneAny {
+    /// Returns `true` if the underlying type is of type `T`
+    pub fn is<T: Any>(&self) -> bool {
+        self.as_any().is::<T>()
+    }
+
+    /// Returns a reference to the concrete value if it is of type `T`, or `None` otherwise.
+    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
+        self.as_any().downcast_ref::<T>()
+    }
+
+    /// Returns a mutable reference to the concrete value if it is of type `T`, or `None` otherwise.
+    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
+        self.as_mut_any().downcast_mut::<T>()
+    }
+}
+
+impl<T: Any + Clone> CloneAny for T {
+    fn clone_box(&self) -> Box<dyn CloneAny> {
+        // Prevent infinite recursion if T is a nested Box type.
+        if let Some(boxed) = self.as_any().downcast_ref::<Box<dyn CloneAny>>() {
+            return (**boxed).clone_box();
+        }
+        Box::new(self.clone())
+    }
+
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn as_mut_any(&mut self) -> &mut dyn Any {
+        self
+    }
+}
+
+impl Clone for Box<dyn CloneAny> {
+    fn clone(&self) -> Self {
+        self.clone_box()
+    }
+}
+
+/// Type alias for a type-erased corpus value.
+pub type GenericCorpusValue = Box<dyn CloneAny>;
+
+/// Type alias for a type-erased user value.
+pub type GenericUserValue = Box<dyn CloneAny>;
+
+/// A trait for types that represent a set of values that an input can take.
+///
+/// Domain types are used to represent the domain of values that a fuzz test input can take
+/// throughout the fuzzing process.
+/// Domain types are used by the fuzzing engine through the APIs defined in this trait.
+///
+/// ## Serialization/Deserialization of CorpusValue and UserValue relationship.
+///
+/// The values drawn from a domain are always of type `CorpusValue`. These values are the
+/// internal representation of the value and they are not directly usable by the fuzz property
+/// function.
+///
+/// The `get_user_value` method is used to retrieve the user value from the corpus value. For
+/// example, if the domain outputs an `&str` then the CorpusValue could be a `String` and the
+/// `get_user_value` method would be used to retrieve the `&str` from the `String`.
+///
+/// The `parse_corpus` (resp. `serialize_corpus`) method is used deserialize (resp. serialize)
+/// the corpus value from (to) a slice of bytes (resp. a vector of bytes).
+///
+/// ### Relationship diagram
+///
+/// The methods below are responsible for transforming between `UserValue`, `CorpusValue`, and the
+/// serialized representation of `CorpusValue`. Here's a quick overview:
+///
+/// ```text
+///        +-- get_user_value() <---+     +-- parse_corpus() <---+
+///        |                        |     |                      |
+///        v                        |     v                      |
+///   UserValue<'a>               CorpusValue                  &[u8]
+///                                       |                      ^
+///                                       |                      |
+///                                       +-> serialize_corpus() +
+/// ```
+pub trait Domain {
+    /// The type of the values that the domain outputs. This should of the same type as the
+    /// parameter of the fuzz property function.
+    type UserValue<'user>;
+    /// The type of the corpus from which the values of type UserValue are drawn.
+    /// For example, if the domain should output an `&str` then the UserValue should be `&str` and
+    /// the CorpusValue could the owned data structured that the `&str` points to (eg: String).
+    /// The CorpusValue type should implement `serde::Serialize`, `serde::de::DeserializeOwned` and
+    /// `Clone`.
+    type CorpusValue: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone;
+
+    /// Initializes a new value drawn from the domain.
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue>;
+
+    /// Mutates the value in `val` to a new value drawn from the domain.
+    ///
+    /// If `only_shrink` is `true`, then the mutation must not increase the size of the corpus
+    /// value. Otherwise, the mutation can both shrink and grow the corpus value.
+    fn mutate(
+        &self,
+        val: &mut Self::CorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()>;
+
+    /// Retrieves a UserValue from a given CorpusValue.
+    ///
+    /// This is used to convert the corpus value into the user value that can then be passed to the
+    /// fuzz property function.
+    fn get_user_value<'a>(
+        &self,
+        corpus_value: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>>;
+
+    /// Turns a slice of bytes into `CorpusValue`.
+    ///
+    /// By default, it uses Postcard to deserialize the data.
+    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<Self::CorpusValue> {
+        postcard::from_bytes(data).context("Failed to deserialize corpus value from bytes")
+    }
+
+    /// Serializes `corpus_value` to a Vec of bytes (ie, Vec<u8>).
+    ///
+    /// By default, it uses Postcard to serialize the data.
+    fn serialize_corpus(&self, corpus_value: &Self::CorpusValue) -> anyhow::Result<Vec<u8>> {
+        postcard::to_stdvec(corpus_value).context("Failed to serialize corpus value to bytes")
+    }
+}
+
+/// A type-erased interface for Domain types.
+///
+/// This trait is used to expose a common interface for Domain types to the fuzzing engine through
+/// the `FuzzTest` trait.
+/// The methods of this trait are similar to that of the `Domain` trait, but they operate on
+/// a type-erased `GenericCorpusValue` instead of an explicit type.
+pub trait GenericDomain {
+    /// Initializes a new value drawn from the domain.
+    ///
+    /// See `Domain::init` for more details.
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue>;
+
+    /// Mutates the value in `val` to a new value drawn from the domain.
+    ///
+    /// See `Domain::mutate` for more details.
+    fn mutate(
+        &self,
+        val: &mut GenericCorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()>;
+
+    /// Parses a slice of bytes into a `GenericCorpusValue`.
+    ///
+    /// See `Domain::parse_corpus` for more details.
+    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<GenericCorpusValue>;
+
+    /// Serializes a `GenericCorpusValue` to a Vec of bytes (ie, Vec<u8>).
+    ///
+    /// See `Domain::serialize_corpus` for more details.
+    fn serialize_corpus(&self, val: &GenericCorpusValue) -> anyhow::Result<Vec<u8>>;
+}
+
+/// Blanket implementation of the `GenericDomain` trait for types implementing the `Domain` trait.
+///
+/// This implementation is a simple pass-through implementation that uses the methods of the
+/// `Domain` trait to implement the `GenericDomain` trait.
+impl<D> GenericDomain for D
+where
+    D: Domain,
+    D::CorpusValue: 'static,
+{
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<GenericCorpusValue> {
+        Ok(Box::new(self.init(rng)?))
+    }
+
+    /// Retrieves the underlying `Domain`'s `CorpusValue` from the `GenericCorpusValue` and calls
+    /// the underlying `Domain::mutate` method.
+    ///
+    /// If the `GenericCorpusValue` cannot be downcasted to the underlying `Domain`'s `CorpusValue`
+    /// then an Error is returned.
+    ///
+    /// See `GenericDomain::mutate` for more details.
+    fn mutate(
+        &self,
+        val: &mut GenericCorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        self.mutate(
+            val.downcast_mut().context("Failed to retrieve the Corpus Value")?,
+            rng,
+            only_shrink,
+        )
+    }
+
+    /// Calls the underlying `Domain::parse_corpus` method with the `data` and wraps the resulting
+    /// `CorpusValue` in a `GenericCorpusValue`.
+    ///
+    /// See `GenericDomain::parse_corpus` for more details.
+    fn parse_corpus(&self, data: &[u8]) -> anyhow::Result<GenericCorpusValue> {
+        Ok(Box::new(self.parse_corpus(data)?))
+    }
+
+    /// Retrieves the underlying `Domain`'s `CorpusValue` from the `GenericCorpusValue` and calls
+    /// the underlying `Domain::serialize_corpus` method.
+    ///
+    /// If the `GenericCorpusValue` cannot be downcasted to the underlying `Domain`'s `CorpusValue`
+    /// then an Error is returned.
+    ///
+    /// See `GenericDomain::serialize_corpus` for more details.
+    fn serialize_corpus(&self, val: &GenericCorpusValue) -> anyhow::Result<Vec<u8>> {
+        self.serialize_corpus(val.downcast_ref().context("Failed to retrieve the Corpus Value")?)
+    }
+}
diff --git a/rust/src/domains/arbitrary.rs b/rust/src/domains/arbitrary.rs
new file mode 100644
index 0000000..07d7db5
--- /dev/null
+++ b/rust/src/domains/arbitrary.rs
@@ -0,0 +1,763 @@
+use super::utility::choose_value;
+use super::utility::mutate_integer;
+use super::utility::shrink_towards;
+use super::Domain;
+
+use anyhow;
+use rand::RngExt;
+
+/// Generates arbitrary values of type `T`.
+///
+/// This domain is used to generate values of a specific type without any constraints
+/// beyond the type's intrinsic range. For example, `Arbitrary<i32>` generates `i32`
+/// values spanning the whole `i32` domain `[i32::MIN, i32::MAX]`.
+///
+/// Example usage:
+/// ```
+/// # use fuzztest::domains::Domain;
+/// # use fuzztest::domains::arbitrary::Arbitrary;
+/// # use rand::rngs::SmallRng;
+/// # use rand::SeedableRng;
+///
+/// let arbitrary_i32 = Arbitrary::<i32>::default();
+/// let mut rng = SmallRng::seed_from_u64(73);
+///
+/// let sample = arbitrary_i32.init(&mut rng);
+/// assert!(sample.is_ok());
+/// ```
+
+pub struct Arbitrary<T> {
+    _phantom: std::marker::PhantomData<T>,
+}
+
+// We cannot just use `#[derive(Default)]` because `T` might not be `Default`.
+impl<T> Default for Arbitrary<T> {
+    fn default() -> Self {
+        Self { _phantom: std::marker::PhantomData }
+    }
+}
+
+impl<T> Arbitrary<T> {
+    /// Creates a new `Arbitrary` domain for the given type `T`.
+    pub fn new() -> Self {
+        Self { _phantom: std::marker::PhantomData }
+    }
+}
+
+impl Domain for Arbitrary<bool> {
+    type UserValue<'user> = bool;
+    type CorpusValue = bool;
+
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        Ok(rng.random())
+    }
+
+    fn mutate(
+        &self,
+        val: &mut Self::CorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        if only_shrink {
+            // Convention taken from the C++ fuzztest library.
+            *val = false;
+        } else {
+            *val = rng.random();
+        }
+        Ok(())
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        corpus_value: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(*corpus_value)
+    }
+}
+
+macro_rules! impl_domain_for_integer {
+    // We need an additional "integer type" for this, because
+    // rand::distr::Distribution<> is not implemented for StandardUniform for isize and usize.
+    // so we perform the generation using integer types and cast to the size types if needed.
+    ($ty:ty, $int_ty:ty) => {
+        impl Domain for Arbitrary<$ty> {
+            type UserValue<'user> = $ty;
+            type CorpusValue = $ty;
+
+            fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+                // We generate a the equivalent integer type so this works for size types.
+                let val: $int_ty = choose_value(rng);
+                Ok(val as $ty)
+            }
+
+            fn mutate(
+                &self,
+                val: &mut Self::CorpusValue,
+                rng: &mut dyn rand::Rng,
+                only_shrink: bool,
+            ) -> anyhow::Result<()> {
+                if only_shrink {
+                    *val = shrink_towards(rng, *val as $int_ty, 0) as $ty;
+                } else {
+                    let original_val = *val;
+                    loop {
+                        *val = mutate_integer(rng, *val as $int_ty, 5, None, None) as $ty;
+                        if *val != original_val {
+                            break;
+                        }
+                    }
+                }
+                Ok(())
+            }
+
+            fn get_user_value<'a>(
+                &self,
+                corpus_value: &'a Self::CorpusValue,
+            ) -> anyhow::Result<Self::UserValue<'a>> {
+                Ok(*corpus_value)
+            }
+        }
+    };
+}
+
+impl_domain_for_integer!(i8, i8);
+impl_domain_for_integer!(u8, u8);
+impl_domain_for_integer!(i16, i16);
+impl_domain_for_integer!(u16, u16);
+impl_domain_for_integer!(i32, i32);
+impl_domain_for_integer!(u32, u32);
+impl_domain_for_integer!(i64, i64);
+impl_domain_for_integer!(u64, u64);
+impl_domain_for_integer!(i128, i128);
+impl_domain_for_integer!(u128, u128);
+impl_domain_for_integer!(isize, i64);
+impl_domain_for_integer!(usize, u64);
+
+macro_rules! impl_domain_for_float {
+    ($ty:ty) => {
+        impl Domain for Arbitrary<$ty> {
+            type UserValue<'user> = $ty;
+            type CorpusValue = $ty;
+
+            fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+                Ok(choose_value(rng))
+            }
+
+            fn mutate(
+                &self,
+                val: &mut Self::CorpusValue,
+                rng: &mut dyn rand::Rng,
+                only_shrink: bool,
+            ) -> anyhow::Result<()> {
+                if only_shrink {
+                    // Shrink only finite, non-terminal values.
+                    if val.is_finite() && *val != 0.0 {
+                        *val = shrink_towards(rng, *val, 0.0);
+                    }
+                    return Ok(());
+                }
+                // Non-shrinking mutation.
+                let original_val = *val;
+                loop {
+                    // Loop to ensure mutation
+                    if !val.is_finite() {
+                        // NaN or Infinity
+                        *val = self.init(rng)?;
+                    } else {
+                        match rng.random_range(0..4) {
+                            0 => *val /= 2.0,
+                            1 => *val = -*val,
+                            2 => *val += 1.0,
+                            3 => *val *= 3.0,
+                            _ => unreachable!(),
+                        }
+                    }
+
+                    if (val.is_nan() && original_val.is_nan()) || *val == original_val {
+                        continue;
+                    }
+                    break;
+                }
+                Ok(())
+            }
+
+            fn get_user_value<'a>(
+                &self,
+                corpus_value: &'a Self::CorpusValue,
+            ) -> anyhow::Result<Self::UserValue<'a>> {
+                Ok(*corpus_value)
+            }
+        }
+    };
+}
+
+impl_domain_for_float!(f32);
+impl_domain_for_float!(f64);
+
+const SURROGATE_START: u32 = 0xD800;
+const SURROGATE_END: u32 = 0xDFFF;
+const MAX_VALID_CODEPOINT: u32 = 0x10FFFF;
+const NUM_VALID_CODEPOINTS: u32 = MAX_VALID_CODEPOINT - (SURROGATE_END - SURROGATE_START);
+
+/// Maps a `char` to a `u32` in a contiguous range.
+///
+/// Rust's `char` type represents a Unicode Scalar Value, which means it cannot be a
+/// surrogate code point (U+D800 to U+DFFF). This function maps `char` values to a
+/// contiguous integer range by shifting down the code points that are above the
+/// surrogate range. This is useful for mutation strategies like random walks over
+/// a dense integer space.
+fn map_char_to_int(c: char) -> u32 {
+    let val = c as u32;
+    if val >= SURROGATE_START {
+        val - (SURROGATE_END - SURROGATE_START + 1)
+    } else {
+        val
+    }
+}
+
+/// Maps a `u32` from the contiguous range back to a `char`.
+///
+/// This is the inverse of `map_char_to_int`. It converts an integer from the
+/// dense range back to a `char`. Integers that fall within the range previously
+/// occupied by surrogates are shifted up to their correct code points.
+fn map_int_to_char(u: u32) -> char {
+    assert!(
+        u < NUM_VALID_CODEPOINTS,
+        "input to map_int_to_char out of range: got {}, expected value < {}",
+        u,
+        NUM_VALID_CODEPOINTS
+    );
+    let val = if u >= SURROGATE_START { u + (SURROGATE_END - SURROGATE_START + 1) } else { u };
+    std::char::from_u32(val).unwrap()
+}
+
+impl Domain for Arbitrary<char> {
+    type UserValue<'user> = char;
+    type CorpusValue = char;
+
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        Ok(choose_value(rng))
+    }
+
+    fn mutate(
+        &self,
+        val: &mut Self::CorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        if only_shrink {
+            // Shrink towards the null character (0 as char).
+            *val = shrink_towards(rng, *val, 0 as char);
+        } else {
+            let original_val = *val;
+            loop {
+                // Map the current char to a u32 in a contiguous range.
+                let mapped_val = map_char_to_int(*val);
+                // Mutate the u32 value within the valid range of mapped code points.
+                let mutated_mapped_val =
+                    mutate_integer(rng, mapped_val, 5, Some(0), Some(NUM_VALID_CODEPOINTS - 1));
+                // Map the mutated u32 back to a char.
+                *val = map_int_to_char(mutated_mapped_val);
+                if *val != original_val {
+                    break;
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        corpus_value: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(*corpus_value)
+    }
+}
+
+impl Domain for Arbitrary<()> {
+    type UserValue<'user> = ();
+    type CorpusValue = ();
+
+    fn init(&self, _rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        Ok(())
+    }
+
+    fn mutate(
+        &self,
+        _val: &mut Self::CorpusValue,
+        _rng: &mut dyn rand::Rng,
+        _only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        // No possible mutation for the unit type
+        Ok(())
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        _corpus_value: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::collections::HashSet;
+
+    use crate::domains::utility::SpecialValues;
+    use num_traits::{Float, One, Zero};
+    use rand::distr::uniform::SampleUniform;
+    use rand::distr::{Distribution, StandardUniform};
+    use rand::rngs::{SmallRng, SysRng};
+    use rand::SeedableRng;
+
+    use crate::domains::Domain;
+
+    use super::*;
+
+    type CorpusValueForArbitrary<T> = <Arbitrary<T> as Domain>::CorpusValue;
+
+    fn get_rng() -> SmallRng {
+        SmallRng::try_from_rng(&mut SysRng).unwrap()
+    }
+
+    /// Trait to be able to treat numerical types uniformly w.r.t. finiteness and shrinking target.
+    trait NumTraitsExtended {
+        fn is_finite_value(&self) -> bool;
+        fn is_at_shrink_target(&self) -> bool;
+    }
+
+    macro_rules! impl_num_traits_extended_for_floats {
+        ($($ty:ty),*) => {
+            $(
+                impl NumTraitsExtended for $ty {
+                    fn is_finite_value(&self) -> bool {
+                        self.is_finite()
+                    }
+                    fn is_at_shrink_target(&self) -> bool {
+                        // We arbitrarily use EPSILON^2 as the accuracy margin for approximate equality.
+                        self.abs() < <$ty>::EPSILON * <$ty>::EPSILON
+                    }
+                }
+            )*
+        };
+    }
+
+    impl_num_traits_extended_for_floats!(f32, f64);
+
+    macro_rules! impl_num_traits_extended_for_non_floats {
+        ($($ty:ty),*) => {
+            $(
+                impl NumTraitsExtended for $ty {
+                    fn is_finite_value(&self) -> bool {
+                        true
+                    }
+                    fn is_at_shrink_target(&self) -> bool {
+                        *self == <$ty>::default()
+                    }
+                }
+            )*
+        };
+    }
+
+    impl_num_traits_extended_for_non_floats!(
+        i8,
+        i16,
+        i32,
+        i64,
+        i128,
+        isize,
+        u8,
+        u16,
+        u32,
+        u64,
+        u128,
+        usize,
+        bool,
+        char,
+        ()
+    );
+
+    fn test_arbitrary_mutations_change_value<T>()
+    where
+        for<'user> Arbitrary<T>: Domain<UserValue<'user> = T>,
+        CorpusValueForArbitrary<T>:
+            std::fmt::Debug + Default + Clone + Copy + PartialOrd + PartialEq + 'static,
+    {
+        let domain = Arbitrary::<T>::default();
+        let mut rng = get_rng();
+        let mut value = domain.init(&mut rng).unwrap();
+
+        // Mutation is guaranteed to change the value.
+        for _ in 0..100 {
+            let original_value = value;
+            domain.mutate(&mut value, &mut rng, false).unwrap();
+            assert_ne!(
+                value,
+                original_value,
+                "Mutation did not change the value for type {}",
+                std::any::type_name::<T>()
+            );
+        }
+    }
+
+    fn test_arbitrary_mutations_generates_diverse_values<T>()
+    where
+        for<'user> Arbitrary<T>: Domain<UserValue<'user> = T>,
+        CorpusValueForArbitrary<T>: std::fmt::Debug
+            + Default
+            + Clone
+            + Copy
+            + PartialOrd
+            + PartialEq
+            + Eq
+            + std::hash::Hash
+            + 'static,
+    {
+        let domain = Arbitrary::<T>::default();
+        let mut rng = get_rng();
+        for _ in 0..100 {
+            let mut value = domain.init(&mut rng).unwrap();
+            let mut values = HashSet::new();
+            values.insert(value);
+
+            for _ in 0..100 {
+                domain.mutate(&mut value, &mut rng, false).unwrap();
+                values.insert(value);
+            }
+            assert!(
+                values.len() >= 50,
+                "Mutation did not generate diverse values for type {}: found {} distinct values, expected >= 50",
+                std::any::type_name::<T>(),
+                values.len()
+            );
+        }
+    }
+
+    fn test_arbitrary_shrinking_reduces_and_terminates<T>()
+    where
+        for<'user> Arbitrary<T>: Domain<UserValue<'user> = T>,
+        CorpusValueForArbitrary<T>: std::fmt::Debug
+            + Default
+            + Clone
+            + Copy
+            + PartialOrd
+            + PartialEq
+            + NumTraitsExtended
+            + 'static,
+    {
+        let domain = Arbitrary::<T>::default();
+        let mut rng = get_rng();
+
+        // Get a value that is not the shrink target
+        let shrink_target = CorpusValueForArbitrary::<T>::default();
+        let mut value;
+        loop {
+            value = domain.init(&mut rng).unwrap();
+            if !value.is_at_shrink_target() && value.is_finite_value() {
+                break;
+            }
+        }
+
+        for _ in 0..1000 {
+            let prev_value = value;
+            domain.mutate(&mut value, &mut rng, true).unwrap();
+
+            if value.is_at_shrink_target() {
+                // Ensure that once the shrink target is reached, further shrinking doesn't change it.
+                domain.mutate(&mut value, &mut rng, true).unwrap();
+                assert!(
+                    value.is_at_shrink_target(),
+                    "Shrinking past the target changed the value for type {}",
+                    std::any::type_name::<T>()
+                );
+                return;
+            }
+
+            // Check progress
+            if prev_value > shrink_target {
+                assert!(
+                    value < prev_value,
+                    "Value should decrease when shrinking towards target from above. Type: {}, Prev: {:?}, Current: {:?}",
+                    std::any::type_name::<T>(),
+                    prev_value,
+                    value
+                );
+                assert!(
+                    value >= shrink_target,
+                    "Value should not shrink past the target from above. Type: {}, Prev: {:?}, Current: {:?}, Target: {:?}",
+                    std::any::type_name::<T>(),
+                    prev_value,
+                    value,
+                    shrink_target
+                );
+            } else {
+                // prev_value < shrink_target
+                assert!(
+                    value > prev_value,
+                    "Value should increase when shrinking towards target from below. Type: {}, Prev: {:?}, Current: {:?}",
+                    std::any::type_name::<T>(),
+                    prev_value,
+                    value
+                );
+                assert!(
+                    value <= shrink_target,
+                    "Value should not shrink past the target from below. Type: {}, Prev: {:?}, Current: {:?}, Target: {:?}",
+                    std::any::type_name::<T>(),
+                    prev_value,
+                    value,
+                    shrink_target
+                );
+            }
+        }
+
+        panic!(
+            "Shrinking did not terminate in 1000 iterations for type {}",
+            std::any::type_name::<T>()
+        );
+    }
+
+    fn test_arbitrary<T>()
+    where
+        for<'user> Arbitrary<T>: Domain<UserValue<'user> = T>,
+        CorpusValueForArbitrary<T>: std::fmt::Debug
+            + Default
+            + Clone
+            + Copy
+            + PartialOrd
+            + PartialEq
+            + Eq
+            + std::hash::Hash
+            + NumTraitsExtended
+            + 'static,
+    {
+        test_arbitrary_mutations_change_value::<T>();
+        test_arbitrary_mutations_generates_diverse_values::<T>();
+        test_arbitrary_shrinking_reduces_and_terminates::<T>();
+    }
+
+    #[test]
+    fn test_i8() {
+        test_arbitrary::<i8>();
+    }
+    #[test]
+    fn test_u8() {
+        test_arbitrary::<u8>();
+    }
+    #[test]
+    fn test_i16() {
+        test_arbitrary::<i16>();
+    }
+    #[test]
+    fn test_u16() {
+        test_arbitrary::<u16>();
+    }
+    #[test]
+    fn test_i32() {
+        test_arbitrary::<i32>();
+    }
+    #[test]
+    fn test_u32() {
+        test_arbitrary::<u32>();
+    }
+    #[test]
+    fn test_i64() {
+        test_arbitrary::<i64>();
+    }
+    #[test]
+    fn test_u64() {
+        test_arbitrary::<u64>();
+    }
+    #[test]
+    fn test_i128() {
+        test_arbitrary::<i128>();
+    }
+    #[test]
+    fn test_u128() {
+        test_arbitrary::<u128>();
+    }
+    #[test]
+    fn test_isize() {
+        test_arbitrary::<isize>();
+    }
+    #[test]
+    fn test_usize() {
+        test_arbitrary::<usize>();
+    }
+
+    #[test]
+    fn test_char() {
+        test_arbitrary::<char>();
+    }
+
+    fn test_bool_shrink() {
+        let domain = Arbitrary::<bool>::default();
+        let mut rng = get_rng();
+        let mut value = true;
+        domain.mutate(&mut value, &mut rng, true).unwrap();
+        assert_eq!(value, false);
+        domain.mutate(&mut value, &mut rng, true).unwrap();
+        assert_eq!(value, false);
+    }
+
+    #[test]
+    fn test_bool() {
+        test_arbitrary_shrinking_reduces_and_terminates::<bool>();
+        test_bool_shrink();
+    }
+    #[test]
+    fn test_unit() {
+        let mut rng = get_rng();
+        let domain = Arbitrary::<()>::default();
+
+        // init() always returns ()
+        assert_eq!(domain.init(&mut rng).unwrap(), ());
+
+        // mutate (non-shrinking) always returns ()
+        let mut value = ();
+        domain.mutate(&mut value, &mut rng, false).unwrap();
+        assert_eq!(value, ());
+
+        // mutate (shrinking) always returns ()
+        let mut value = ();
+        domain.mutate(&mut value, &mut rng, true).unwrap();
+        assert_eq!(value, ());
+    }
+
+    fn test_float_special_value_shrink<T>()
+    where
+        for<'user> Arbitrary<T>: Domain<UserValue<'user> = T>,
+        CorpusValueForArbitrary<T>:
+            Float + SampleUniform + std::fmt::Display + std::fmt::Debug + SpecialValues + 'static,
+        StandardUniform: Distribution<T>,
+    {
+        let domain = Arbitrary::<T>::default();
+        let mut rng = get_rng();
+
+        // Positive.
+        let mut v = CorpusValueForArbitrary::<T>::one();
+        let original_v = v;
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert!(
+            v >= CorpusValueForArbitrary::<T>::zero() && v < original_v,
+            "Shrinking {} to {}",
+            original_v,
+            v
+        );
+
+        // Negative.
+        let mut v = -CorpusValueForArbitrary::<T>::one();
+        let original_v = v;
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert!(
+            v > original_v && v <= CorpusValueForArbitrary::<T>::zero(),
+            "Shrinking {} to {}",
+            original_v,
+            v
+        );
+
+        // Zero.
+        let mut v = CorpusValueForArbitrary::<T>::zero();
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert_eq!(v, CorpusValueForArbitrary::<T>::zero());
+
+        let mut v = CorpusValueForArbitrary::<T>::neg_zero();
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert_eq!(v, CorpusValueForArbitrary::<T>::neg_zero());
+
+        // NaN / Inf are not changed by this shrink implementation.
+        let mut v = CorpusValueForArbitrary::<T>::nan();
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert!(v.is_nan(), "NaN should remain NaN");
+
+        let mut v = CorpusValueForArbitrary::<T>::infinity();
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert!(v.is_infinite() && v.is_sign_positive(), "Infinity should remain Infinity");
+
+        let mut v = CorpusValueForArbitrary::<T>::neg_infinity();
+        domain.mutate(&mut v, &mut rng, true).unwrap();
+        assert!(v.is_infinite() && v.is_sign_negative(), "Neg Infinity should remain Neg Infinity");
+    }
+
+    #[test]
+    fn test_f32() {
+        test_arbitrary_mutations_change_value::<f32>();
+        test_arbitrary_shrinking_reduces_and_terminates::<f32>();
+        test_float_special_value_shrink::<f32>();
+    }
+
+    #[test]
+    fn test_f64() {
+        test_arbitrary_mutations_change_value::<f64>();
+        test_arbitrary_shrinking_reduces_and_terminates::<f64>();
+        test_float_special_value_shrink::<f64>();
+    }
+
+    #[test]
+    fn test_char_mutate_boundaries() {
+        let domain = Arbitrary::<char>::default();
+        let mut rng = get_rng();
+        let mut val = '\u{0000}';
+        domain.mutate(&mut val, &mut rng, false).unwrap();
+        assert!(val >= '\u{0000}');
+
+        val = '\u{10FFFF}';
+        domain.mutate(&mut val, &mut rng, false).unwrap();
+        assert!(val <= '\u{10FFFF}');
+
+        val = '\u{D7FF}'; // Before surrogate
+        domain.mutate(&mut val, &mut rng, false).unwrap();
+
+        val = '\u{E000}'; // After surrogate
+        domain.mutate(&mut val, &mut rng, false).unwrap();
+    }
+
+    #[test]
+    fn test_char_mapping() {
+        // Test boundary conditions and values around the surrogate range
+        assert_eq!(map_char_to_int('\u{0000}'), 0);
+        assert_eq!(map_int_to_char(0), '\u{0000}');
+
+        let before_surrogate = SURROGATE_START - 1;
+        assert_eq!(
+            map_char_to_int(std::char::from_u32(before_surrogate).unwrap()),
+            before_surrogate
+        );
+        assert_eq!(
+            map_int_to_char(before_surrogate),
+            std::char::from_u32(before_surrogate).unwrap()
+        );
+
+        let after_surrogate = SURROGATE_END + 1;
+        let mapped_after_surrogate = map_char_to_int(std::char::from_u32(after_surrogate).unwrap());
+        assert_eq!(mapped_after_surrogate, SURROGATE_START);
+        assert_eq!(map_int_to_char(SURROGATE_START), std::char::from_u32(after_surrogate).unwrap());
+
+        assert_eq!(map_char_to_int('\u{10FFFF}'), NUM_VALID_CODEPOINTS - 1);
+        assert_eq!(map_int_to_char(NUM_VALID_CODEPOINTS - 1), '\u{10FFFF}');
+    }
+
+    #[test]
+    fn test_char_shrink_to_null() {
+        for _ in 0..10 {
+            let domain = Arbitrary::<char>::default();
+            let mut rng = get_rng();
+            let mut value = domain.init(&mut rng).unwrap();
+
+            let mut iterations = 0;
+            const MAX_ITERATIONS: u32 = 100_000;
+
+            while value != '\0' && iterations < MAX_ITERATIONS {
+                domain.mutate(&mut value, &mut rng, true).unwrap();
+                // Ensure that the value is always a valid char after mutation.
+                assert!(std::char::from_u32(value as u32).is_some());
+                iterations += 1;
+            }
+            assert_eq!(
+                value, '\0',
+                "Char did not shrink to null within {} iterations. Final value: {}",
+                MAX_ITERATIONS, value
+            );
+        }
+    }
+}
diff --git a/rust/src/domains/range.rs b/rust/src/domains/range.rs
new file mode 100644
index 0000000..fd44e20
--- /dev/null
+++ b/rust/src/domains/range.rs
@@ -0,0 +1,85 @@
+use super::Domain;
+
+use anyhow;
+use rand::distr::uniform::SampleUniform;
+use rand::distr::uniform::UniformSampler;
+
+/// Generates values of type `T` in a given range.
+///
+/// For example, `InRange::new(0, 100)` generates integer
+/// values from the inclusive range `[0, 100]`.
+///
+/// Example usage:
+/// ```
+/// # use fuzztest::domains::Domain;
+/// # use fuzztest::domains::range::InRange;
+/// # use rand::prelude::*;
+///
+/// let range_i32 = InRange::new(21i32, 73);
+/// let sample = range_i32.init(&mut rand::rng());
+///
+/// assert!(sample.is_ok());
+/// let sample = sample.unwrap();
+/// assert!(sample >= 21);
+/// assert!(sample <= 73);
+/// ```
+pub struct InRange<T> {
+    lower: T,
+    upper: T,
+}
+
+impl InRange<i32> {
+    pub fn new(lower: i32, upper: i32) -> Self {
+        Self { lower, upper }
+    }
+
+    pub fn get_in_range(&self, rng: &mut dyn rand::Rng) -> i32 {
+        <i32 as SampleUniform>::Sampler::sample_single(self.lower, self.upper, rng)
+            .expect("Failed to sample from Uniform distribution")
+    }
+}
+
+impl Domain for InRange<i32> {
+    type UserValue<'user> = i32;
+    type CorpusValue = i32;
+
+    fn init(&self, rng: &mut dyn rand::Rng) -> anyhow::Result<Self::CorpusValue> {
+        Ok(self.get_in_range(rng))
+    }
+
+    fn mutate(
+        &self,
+        val: &mut Self::CorpusValue,
+        rng: &mut dyn rand::Rng,
+        only_shrink: bool,
+    ) -> anyhow::Result<()> {
+        if only_shrink {
+            *val -= 1;
+        } else {
+            *val = self.get_in_range(rng);
+        }
+        Ok(())
+    }
+
+    fn get_user_value<'a>(
+        &self,
+        corpus_value: &'a Self::CorpusValue,
+    ) -> anyhow::Result<Self::UserValue<'a>> {
+        Ok(*corpus_value)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use rand::SeedableRng;
+
+    use super::*;
+
+    #[test]
+    fn test_in_range() {
+        let in_range = InRange::<i32>::new(0, 100);
+        let mut rng = rand::rngs::StdRng::from_seed([73; 32]);
+        let in_range_val = in_range.get_in_range(&mut rng);
+        assert!(in_range_val >= 0 && in_range_val <= 100);
+    }
+}
diff --git a/rust/src/domains/tuple_of.rs b/rust/src/domains/tuple_of.rs
new file mode 100644
index 0000000..ac63964
--- /dev/null
+++ b/rust/src/domains/tuple_of.rs
@@ -0,0 +1,6 @@
+// TODO(yamilmorales, tinmar, mathuxny-73): Replace generated wrapper domain (to deduplicate
+// implementations for tests with the same number of parameters) with these, meaning we should
+// `impl Domain` on these tuples.
+
+pub type TupleOf1<T0> = (T0,);
+pub type TupleOf2<T0, T1> = (T0, T1);
diff --git a/rust/src/domains/utility.rs b/rust/src/domains/utility.rs
new file mode 100644
index 0000000..2d63441
--- /dev/null
+++ b/rust/src/domains/utility.rs
@@ -0,0 +1,404 @@
+use std::cmp::Ordering;
+
+use num_traits::PrimInt;
+use rand::distr::uniform::SampleUniform;
+use rand::distr::{Distribution, StandardUniform};
+use rand::RngExt;
+
+/// Shrinks a `val` towards a `target` value.
+///
+/// The new value is chosen uniformly from the range between `val` and `target`.
+/// - If `val > target`, the range is `[target, val)`.
+/// - If `val < target`, the range is `(val, target]`.
+/// - If `val == target`, `val` is returned.
+///
+/// # Arguments
+/// * `rng`: Random number generator.
+/// * `val`: The current value to shrink.
+/// * `target`: The value to shrink towards.
+pub fn shrink_towards<T, R: rand::Rng + ?Sized>(rng: &mut R, val: T, target: T) -> T
+where
+    T: SampleUniform + PartialOrd + Copy + std::fmt::Display,
+{
+    match val.partial_cmp(&target) {
+        Some(Ordering::Equal) => val,
+        Some(Ordering::Less) => {
+            // val < target
+            // Sample from (val, target].
+            // To do that, we sample from [val, target) and return target if we draw val.
+            let sample = rng.random_range(val..target);
+            if sample == val {
+                target
+            } else {
+                sample
+            }
+        }
+        Some(Ordering::Greater) => {
+            // val > target
+            // Sample from [target, val).
+            rng.random_range(target..val)
+        }
+        None => val, // Cannot compare, return original
+    }
+}
+
+/// Mutates an integer value using one of several strategies.
+///
+/// The mutation strategies are:
+/// 1.  Random Walk: Add/subtract a small value within the given `range`.
+/// 2.  Bit Flip: Flip a single random bit.
+/// 3.  Random Choice: Replace with a new completely random value.
+///
+/// # Arguments
+/// * `rng`: Random number generator.
+/// * `val`: The integer value to mutate.
+/// * `range`: The maximum +/- delta for the random walk.
+/// * `min_value`: Optional minimum boundary for mutation. If `None`, `T::min_value()` is used.
+/// * `max_value`: Optional maximum boundary for mutation. If `None`, `T::max_value()` is used.
+// REQUIRES: range > 0
+// REQUIRES: min_value <= max_value (after unwrapping)
+// TODO(b/405382579): Add dictionary-based mutation strategies similar to C++ implementation
+// (See `fuzztest/internal/domains/value_mutation_helpers.h`)
+pub fn mutate_integer<T, R: rand::Rng + ?Sized>(
+    rng: &mut R,
+    val: T,
+    range: T,
+    min_value: Option<T>,
+    max_value: Option<T>,
+) -> T
+where
+    T: PrimInt + SampleUniform + std::fmt::Display,
+{
+    assert!(range > T::zero(), "mutate_integer: range value cannot be <= 0: {range}");
+
+    let min_val = min_value.unwrap_or(T::min_value());
+    let max_val = max_value.unwrap_or(T::max_value());
+    assert!(
+        min_val < max_val,
+        "mutate_integer: min_val must be strictly smaller than max_val: min={min_val}, max={max_val}"
+    );
+
+    match rng.random_range(0..3) {
+        0 => {
+            // 1/3 chance: Random Walk
+            // Establish a window around the current value. If val > max_val, we should walk
+            // around max_val instead to bring the value back into a valid range.
+            let center = val.clamp(min_val, max_val);
+            let lo = center.saturating_sub(range).max(min_val);
+            let hi = center.saturating_add(range).min(max_val);
+
+            // Sample uniformly within the clamped window [lo, hi].
+            rng.random_range(lo..=hi)
+        }
+        1 => {
+            // 1/3 chance: Flip a random bit
+            let num_bits = std::mem::size_of::<T>() * 8;
+            let bit_index = rng.random_range(0..num_bits);
+            let mask = T::one() << bit_index;
+            let result = val ^ mask;
+            if result < min_val || result > max_val {
+                val
+            } else {
+                result
+            }
+        }
+        _ => {
+            // 1/3 chance: Replace with a new random value
+            rng.random_range(min_val..=max_val)
+        }
+    }
+}
+
+pub trait SpecialValues: Sized + Copy {
+    fn get() -> &'static [Self];
+}
+
+macro_rules! impl_special_values_signed {
+    ($($ty:ty),*) => {
+        $(
+            impl SpecialValues for $ty {
+                fn get() -> &'static [Self] {
+                    &[0, 1, -1, <$ty>::MIN, <$ty>::MAX]
+                }
+            }
+        )*
+    };
+}
+
+macro_rules! impl_special_values_unsigned {
+    ($($ty:ty),*) => {
+        $(
+            impl SpecialValues for $ty {
+                fn get() -> &'static [Self] {
+                    &[0, 1, <$ty>::MAX, <$ty>::MAX >> 1]
+                }
+            }
+        )*
+    };
+}
+
+impl_special_values_signed!(i8, i16, i32, i64, i128);
+impl_special_values_unsigned!(u8, u16, u32, u64, u128);
+
+macro_rules! impl_special_values_float {
+    ($($ty:ty),*) => {
+        $(
+            impl SpecialValues for $ty {
+                fn get() -> &'static [Self] {
+                    &[0.0, -0.0, 1.0, -1.0, <$ty>::MIN, <$ty>::MAX, <$ty>::INFINITY, <$ty>::NEG_INFINITY, <$ty>::NAN]
+                }
+            }
+        )*
+    };
+}
+impl_special_values_float!(f32, f64);
+
+impl SpecialValues for char {
+    fn get() -> &'static [Self] {
+        &[
+            '\0',         // Null
+            'a',          // Common ASCII
+            '~',          // Last printable ASCII
+            '\n',         // Newline
+            ' ',          // Space
+            '\u{0080}',   // Start of multi-byte UTF-8
+            '\u{D7FF}',   // Before surrogate range
+            '\u{E000}',   // After surrogate range
+            '\u{10FFFF}', // Max valid Unicode scalar value
+        ]
+    }
+}
+
+/// Chooses a value of type `T`, potentially from a set of "special values".
+///
+/// This function has a higher chance of returning one of the predefined "special values"
+/// for the type `T` (as defined by the `SpecialValues` trait). Otherwise, it generates
+/// a completely random value of type `T`.
+///
+/// # Arguments
+/// * `rng`: Random number generator.
+///
+/// # Type Parameters
+/// * `T`: The type of the value to choose. Must implement `SpecialValues` and
+///        `StandardUniform` must be able to generate values of type `T`.
+pub fn choose_value<T, R: rand::Rng + ?Sized>(rng: &mut R) -> T
+where
+    T: SpecialValues + 'static,
+    StandardUniform: Distribution<T>,
+{
+    let special_values = T::get();
+    let index = rng.random_range(0..=special_values.len());
+    if index < special_values.len() {
+        special_values[index]
+    } else {
+        rng.random()
+    }
+}
+
+/// Mutates a float value.
+pub fn mutate_float<T, R: rand::Rng + ?Sized>(
+    rng: &mut R,
+    val: &mut T,
+    only_shrink: bool,
+    _range: Option<(T, T)>, // TODO: Implement range support for floats.
+) -> anyhow::Result<()>
+where
+    T: num_traits::Float + SampleUniform + std::fmt::Display + Copy + SpecialValues + 'static,
+    StandardUniform: Distribution<T>,
+{
+    if only_shrink {
+        // Shrink only finite, non-terminal values.
+        if val.is_finite() && *val != T::zero() {
+            *val = shrink_towards(rng, *val, T::zero());
+        }
+        return Ok(());
+    }
+    // Non-shrinking mutation.
+    let original_val = *val;
+    loop {
+        // Loop to ensure mutation
+        if !val.is_finite() {
+            // NaN or Infinity
+            *val = choose_value(rng);
+        } else {
+            match rng.random_range(0..4) {
+                0 => *val = *val / (T::one() + T::one()),
+                1 => *val = -*val,
+                2 => *val = *val + T::one(),
+                3 => *val = *val * (T::one() + T::one() + T::one()),
+                _ => unreachable!(),
+            }
+        }
+
+        if (val.is_nan() && original_val.is_nan()) || *val == original_val {
+            continue;
+        }
+        break;
+    }
+    Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use rand::{
+        rngs::{SmallRng, SysRng},
+        SeedableRng,
+    };
+
+    fn get_rng() -> SmallRng {
+        SmallRng::try_from_rng(&mut SysRng).unwrap()
+    }
+
+    fn check_shrink_towards<T>(smaller: T, larger: T)
+    where
+        T: SampleUniform + PartialOrd + Copy + std::fmt::Display + std::fmt::Debug + PartialEq,
+    {
+        let mut rng = get_rng();
+
+        // val > target (e.g. larger -> smaller)
+        // Range should be [smaller, larger)
+        let mut results = Vec::new();
+        for _ in 0..100 {
+            let sample = shrink_towards(&mut rng, larger, smaller);
+            assert!(sample >= smaller && sample < larger);
+            if !results.contains(&sample) {
+                results.push(sample);
+            }
+        }
+        assert!(results.len() > 1);
+
+        // val < target (e.g. smaller -> larger)
+        // Range should be (smaller, larger]
+        let mut results = Vec::new();
+        for _ in 0..100 {
+            let sample = shrink_towards(&mut rng, smaller, larger);
+            assert!(sample > smaller && sample <= larger);
+            if !results.contains(&sample) {
+                results.push(sample);
+            }
+        }
+        assert!(results.len() > 1);
+
+        // identical target
+        let sample = shrink_towards(&mut rng, smaller, smaller);
+        assert_eq!(sample, smaller);
+    }
+
+    #[test]
+    fn test_shrink_towards_all_types() {
+        check_shrink_towards::<i8>(5, 10);
+        check_shrink_towards::<u8>(5, 10);
+        check_shrink_towards::<i16>(5, 10);
+        check_shrink_towards::<u16>(5, 10);
+        check_shrink_towards::<i32>(5, 10);
+        check_shrink_towards::<u32>(5, 10);
+        check_shrink_towards::<i64>(5, 10);
+        check_shrink_towards::<u64>(5, 10);
+        check_shrink_towards::<i128>(5, 10);
+        check_shrink_towards::<u128>(5, 10);
+        check_shrink_towards::<f32>(5.0, 10.0);
+        check_shrink_towards::<f64>(5.0, 10.0);
+    }
+
+    fn check_mutate_integer<T>()
+    where
+        T: PrimInt + SampleUniform + std::fmt::Display + std::fmt::Debug + SpecialValues + 'static,
+        StandardUniform: Distribution<T>,
+    {
+        let mut rng = get_rng();
+
+        let min_val = T::zero();
+        let max_val = T::one() + T::one() + T::one() + T::one() + T::one();
+        let range = T::one() + T::one();
+
+        // Bounded mutation stays in bounds
+        for _ in 0..100 {
+            let val: T = choose_value(&mut rng).clamp(min_val, max_val);
+            let next = mutate_integer(&mut rng, val, range, Some(min_val), Some(max_val));
+            assert!(
+                next >= min_val && next <= max_val,
+                "mutate_integer bounded range check failed for value {} not in [{}, {}]",
+                next,
+                min_val,
+                max_val
+            );
+        }
+
+        // Unbounded mutation changes value
+        let mut val = T::zero();
+        let mut changed = false;
+        for _ in 0..100 {
+            let next = mutate_integer(&mut rng, val, range, None, None);
+            if next != val {
+                changed = true;
+                break;
+            }
+            val = next;
+        }
+        assert!(changed, "mutate_integer did not change value");
+    }
+
+    #[test]
+    fn test_mutate_integer_all_types() {
+        check_mutate_integer::<i8>();
+        check_mutate_integer::<u8>();
+        check_mutate_integer::<i16>();
+        check_mutate_integer::<u16>();
+        check_mutate_integer::<i32>();
+        check_mutate_integer::<u32>();
+        check_mutate_integer::<i64>();
+        check_mutate_integer::<u64>();
+        check_mutate_integer::<i128>();
+        check_mutate_integer::<u128>();
+    }
+
+    fn check_mutate_float<T>()
+    where
+        T: num_traits::Float
+            + SampleUniform
+            + std::fmt::Display
+            + std::fmt::Debug
+            + Copy
+            + SpecialValues
+            + 'static,
+        StandardUniform: Distribution<T>,
+    {
+        let mut rng = get_rng();
+
+        // Mutation changes value
+        let mut val = T::one();
+        let mut changed = false;
+        for _ in 0..100 {
+            let mut next = val;
+            mutate_float(&mut rng, &mut next, false, None).unwrap();
+            // Floats might mutate to NaN
+            if next != val || (next.is_nan() && !val.is_nan()) {
+                changed = true;
+                if next.is_nan() {
+                    val = T::one();
+                } else {
+                    val = next;
+                }
+            }
+        }
+        assert!(changed, "mutate_float did not change value");
+
+        // Shrinking
+        let mut val = T::one() + T::one() + T::one();
+        let original_abs = val.abs();
+        for _ in 0..10 {
+            let mut next = val;
+            mutate_float(&mut rng, &mut next, true, None).unwrap();
+            assert!(next.abs() <= val.abs(), "mutate_float shrink increased absolute value");
+            val = next;
+        }
+        assert!(val.abs() < original_abs, "mutate_float did not shrink value");
+    }
+
+    #[test]
+    fn test_mutate_float_all_types() {
+        check_mutate_float::<f32>();
+        check_mutate_float::<f64>();
+    }
+}
diff --git a/rust/src/internal.rs b/rust/src/internal.rs
new file mode 100644
index 0000000..d440b68
--- /dev/null
+++ b/rust/src/internal.rs
@@ -0,0 +1,57 @@
+use super::domains::GenericCorpusValue;
+use super::domains::GenericDomain;
+use std::collections::HashMap;
+use std::sync::LazyLock;
+
+/// A trait implemented by types used to Fuzz a given property function.
+///
+/// When a test is annotated with the `fuzztest` macro attribute, that test will be wrapped in a
+/// FuzzTestObject that implements this trait. The FuzzTestObject is created by the macro and holds,
+/// among others, the property function and the domains of its arguments.
+/// The FuzzTestObject is then manipulated by Fuzzing Test Engine through the APIs of this trait.
+pub trait FuzzTest {
+    // TODO(tinmar): refine arguments as we get a clearer picture of
+    // what the dispatcher interface looks like
+    fn name(&self) -> &'static str;
+    fn activate(&mut self);
+    fn mutate(&mut self);
+    /// Executes the property function with the given arguments
+    /// (will attempt to downcast to actual user values).
+    ///
+    /// Returns `true` if the property function holds, `false` if it crashes.
+    fn execute<'a>(&self, args: &'a GenericCorpusValue) -> bool;
+    fn print_finding_report(&self);
+    fn domains(&self) -> &dyn GenericDomain;
+}
+
+/// Identifies the property function of a fuzz test.
+///
+/// `FuzzTestInfo` is instantiated by the `fuzztest` macro which populates the fields with the
+/// appropriate values.
+pub struct FuzzTestInfo {
+    pub name: &'static str,
+    pub file: &'static str,
+    pub line: u32,
+}
+
+pub type BoxedFuzzTest = Box<dyn FuzzTest + Send + Sync>;
+
+pub struct FuzzTestRegistration {
+    pub info: &'static FuzzTestInfo,
+    pub factory: fn() -> BoxedFuzzTest,
+}
+
+inventory::collect!(FuzzTestRegistration);
+
+pub static FUZZ_TEST_NAME_TO_FACTORY: LazyLock<HashMap<&str, fn() -> BoxedFuzzTest>> =
+    LazyLock::new(|| {
+        inventory::iter
+            .into_iter()
+            .map(|&FuzzTestRegistration { info, factory }| (info.name, factory))
+            .collect()
+    });
+
+pub struct InputStateAndDomain<I, D> {
+    pub input_state: Option<I>,
+    pub domain: D,
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
new file mode 100644
index 0000000..82ee073
--- /dev/null
+++ b/rust/src/lib.rs
@@ -0,0 +1,21 @@
+#![feature(cfg_sanitize)]
+
+mod crash_handler;
+pub mod domains;
+pub mod internal;
+pub mod worker;
+
+pub use fuzztest_macro::fuzztest;
+pub use serde;
+
+pub mod options;
+pub use options::get_fuzztest_options;
+pub use options::FuzzTestOptions;
+
+// Re-export helper crates used in macro expansion to decouple downstream Cargo.toml files.
+#[doc(hidden)]
+pub mod reexports {
+    pub use anyhow;
+    pub use inventory;
+    pub use rand;
+}
diff --git a/rust/src/options.rs b/rust/src/options.rs
new file mode 100644
index 0000000..e765194
--- /dev/null
+++ b/rust/src/options.rs
@@ -0,0 +1,901 @@
+use crate::internal::FuzzTestRegistration;
+use ::engine::engine_ffi;
+use anyhow::Context;
+use clap::{Parser, ValueEnum};
+use humantime::Duration;
+use std::ffi::CString;
+use std::ffi::OsString;
+use std::path::Path;
+use std::sync::OnceLock;
+use tempfile::{NamedTempFile, TempDir};
+
+/// Time budget calculation type for replay corpus mode.
+#[derive(ValueEnum, Debug, Clone, Copy, PartialEq, Eq, Default)]
+pub enum TimeBudgetType {
+    #[default]
+    PerTest,
+    Total,
+}
+
+/// Parses a fuzzing duration string from `FUZZTEST_FUZZ_FOR`.
+///
+/// Matches `"inf"` or `"infinite"` to [`FuzzFor::Indefinitely`]. All other values
+/// are parsed as standard human-readable durations (for example, `"5s"` or `"10m"`).
+fn parse_fuzz_for(s: &str) -> anyhow::Result<FuzzFor> {
+    let s_lower = s.trim().to_lowercase();
+    if s_lower == "inf" || s_lower == "infinite" {
+        Ok(FuzzFor::Indefinitely)
+    } else {
+        let duration = s.parse()?;
+        Ok(FuzzFor::Duration(duration))
+    }
+}
+
+/// Command-line and environment variable options parsed for the FuzzTest harness.
+#[derive(Parser, Debug, Clone, Default)]
+pub struct FuzzTestOptions {
+    /// The working root directory.
+    #[arg(env = "FUZZTEST_WORKDIR_ROOT", long)]
+    pub workdir_root: Option<String>,
+
+    /// The duration for which each test should be fuzzed.
+    ///
+    /// Accepts a human-readable duration (e.g., `5s`, `10m`, `1h`) or `inf` / `infinite`
+    /// to fuzz indefinitely until a crash is found or it is stopped manually.
+    #[arg(env = "FUZZTEST_FUZZ_FOR", long, value_parser = parse_fuzz_for)]
+    pub fuzz_for: Option<FuzzFor>,
+
+    /// If true, subprocess logs are printed after every batch. Note that crash logs are always printed
+    /// regardless of this flag's value.
+    #[arg(env = "FUZZTEST_PRINT_SUBPROCESS_LOG", long)]
+    pub print_subprocess_log: bool,
+
+    /// Number of parallel jobs to run.
+    #[arg(env = "FUZZTEST_JOBS", long)]
+    pub jobs: Option<usize>,
+
+    /// The crash ID to be replayed from the corpus database.
+    ///
+    /// If set, `corpus_db` must also be specified. This mode retrieves the crashing input
+    /// associated with the given ID from the database and executes the property function.
+    #[arg(env = "FUZZTEST_REPLAY_ID", long, requires = "corpus_db")]
+    pub replay_id: Option<String>,
+
+    /// Replay all crashing inputs from the corpus database.
+    #[arg(env = "FUZZTEST_REPLAY_FINDINGS", long)]
+    pub replay_findings: bool,
+
+    /// Replay the corpus for a specified duration.
+    #[arg(env = "FUZZTEST_REPLAY_CORPUS_FOR", long)]
+    pub replay_corpus_for: Option<Duration>,
+
+    /// Time budget calculation type for replay corpus mode.
+    #[arg(env = "FUZZTEST_TIME_BUDGET_TYPE", long, value_enum, default_value_t = TimeBudgetType::PerTest)]
+    pub time_budget_type: TimeBudgetType,
+
+    /// The path to the corpus database.
+    ///
+    /// If set to non-empty, updates/queries the corpus database that contains coverage,
+    /// regression, and crashing inputs for each test binary and fuzz test.
+    #[arg(env = "FUZZTEST_CORPUS_DB", long)]
+    pub corpus_db: Option<String>,
+}
+
+impl FuzzTestOptions {
+    /// Evaluates the raw options and maps them to a strongly-typed domain `ExecutionMode`.
+    ///
+    /// This decouples raw environment/CLI option parsing from execution mode validation.
+    pub fn execution_mode(&self) -> ExecutionMode {
+        if let Some(replay_corpus_for) = self.replay_corpus_for {
+            return ExecutionMode::ReplayCorpus(ReplayCorpusOptions {
+                replay_corpus_for,
+                time_budget_type: self.time_budget_type,
+            });
+        }
+
+        if self.replay_findings {
+            return ExecutionMode::ReplayAllCrashes;
+        }
+
+        if let Some(replay_id) = &self.replay_id {
+            return ExecutionMode::ReplayCrash(ReplayCrashOptions { replay_id: replay_id.clone() });
+        }
+
+        if let Some(fuzz_for) = self.fuzz_for {
+            return ExecutionMode::Fuzz(FuzzOptions { fuzz_for, jobs: self.jobs.clone() });
+        }
+
+        ExecutionMode::SmokeTest
+    }
+}
+
+/// Returns a lazily-initialized static reference to the global `FuzzTestOptions`.
+pub fn get_fuzztest_options() -> &'static FuzzTestOptions {
+    static OPTIONS: OnceLock<FuzzTestOptions> = OnceLock::new();
+    // We parse FuzzTestOptions from an empty iterator so that clap would parse the options only
+    // from environment variables (like `FUZZTEST_FUZZ_FOR` etc.). We (currently) do not envisage
+    // support for passing flags on cli as the Rust's libtest harness does not support custom
+    // flags.
+    OPTIONS.get_or_init(|| FuzzTestOptions::parse_from(std::iter::empty::<OsString>()))
+}
+
+/// Strongly-typed domain execution mode for test runs.
+///
+/// This enum represents the parsed high-level user intent derived from `FuzzTestOptions`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ExecutionMode {
+    /// Smoke test execution (regular unit test fallback).
+    SmokeTest,
+
+    /// Fuzzing mode.
+    Fuzz(FuzzOptions),
+
+    /// Replay a specific crash ID from the corpus database.
+    ReplayCrash(ReplayCrashOptions),
+
+    /// Replay all crashing inputs stored in the corpus database.
+    ReplayAllCrashes,
+
+    /// Replay corpus inputs for a specified duration.
+    ReplayCorpus(ReplayCorpusOptions),
+}
+
+/// Mode-specific options for continuous fuzzing.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct FuzzOptions {
+    pub fuzz_for: FuzzFor,
+
+    /// If `jobs` is `None`, we won't specify the number of jobs while invoking Centipede and it
+    /// will use its own default value.
+    pub jobs: Option<usize>,
+}
+
+/// The duration or limit for fuzzing.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum FuzzFor {
+    /// Fuzz indefinitely until it is manually stopped or a crash is found.
+    Indefinitely,
+
+    /// Fuzz for a specific duration.
+    Duration(Duration),
+}
+
+/// Mode-specific options for replaying a specific database crash.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ReplayCrashOptions {
+    pub replay_id: String,
+}
+
+/// Mode-specific options for replaying corpus for a duration.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ReplayCorpusOptions {
+    pub replay_corpus_for: Duration,
+    pub time_budget_type: TimeBudgetType,
+}
+
+impl ExecutionMode {
+    /// Prepares the concrete `ExecutionAction` payload for execution by building any required
+    /// `CentipedeArgs` or temporary runtime assets.
+    pub fn prepare_action(
+        &self,
+        options: &FuzzTestOptions,
+        current_test_name: Option<&str>,
+    ) -> anyhow::Result<ExecutionAction> {
+        match self {
+            ExecutionMode::SmokeTest => Ok(ExecutionAction::SmokeTest),
+            ExecutionMode::Fuzz(_)
+            | ExecutionMode::ReplayCrash(_)
+            | ExecutionMode::ReplayCorpus(_) => {
+                let centipede_args =
+                    CentipedeArgs::from_execution_mode(self, options, current_test_name, None)?
+                        .context(
+                            "while attempting to build CentipedeArgs for standalone execution mode",
+                        )?;
+                Ok(ExecutionAction::Standalone(centipede_args))
+            }
+            ExecutionMode::ReplayAllCrashes => {
+                let list_file = NamedTempFile::new()
+                    .context("while attempting to create temp file for ReplayAllCrashes")?;
+                let centipede_args = CentipedeArgs::from_execution_mode(
+                    self,
+                    options,
+                    current_test_name,
+                    Some(list_file.path()),
+                )?
+                .context("while attempting to build CentipedeArgs for replay all crashes mode")?;
+                Ok(ExecutionAction::ReplayAllCrashes { args: centipede_args, list_file })
+            }
+        }
+    }
+}
+
+/// The prepared, ready-to-run execution payload passed to the test worker.
+///
+/// This enum bridges parsed domain intent (`ExecutionMode`) with the concrete runtime
+/// assets (`CentipedeArgs`, temporary files, workdir paths) needed to execute the test run.
+#[derive(Debug)]
+pub enum ExecutionAction {
+    /// Run as a smoke test (regular unit test) with random inputs for a short duration.
+    SmokeTest,
+
+    /// Run in standalone mode, invoking the Centipede fuzzing controller.
+    Standalone(CentipedeArgs),
+
+    /// Replay all crash IDs from the database (carries `list_file` for worker post-processing).
+    ReplayAllCrashes { args: CentipedeArgs, list_file: NamedTempFile },
+}
+
+/// Encapsulates command-line arguments and lifetime holders for Centipede execution.
+#[derive(Debug)]
+pub struct CentipedeArgs {
+    // Holds the owned C-compatible strings. We must keep these alive because the `views`
+    // field contains pointers into the memory owned by these `CString`s.
+    _c_strings: Vec<CString>,
+
+    // The (optional) TempDir instance which is to be used as a workdir by centipede.
+    // We keep the ownership here so that it is not cleaned while the centipede execution is still
+    // in progress.
+    _temp_workdir: Option<TempDir>,
+
+    // FFI-compatible views into the arguments in `_c_strings`. These are passed across
+    // the FFI boundary to Centipede.
+    views: Vec<engine_ffi::FuzzTestBytesView>,
+}
+
+impl CentipedeArgs {
+    fn new(args: Vec<CString>, temp_workdir: Option<TempDir>) -> Self {
+        let views = args
+            .iter()
+            .map(|arg| engine_ffi::FuzzTestBytesView::from_bytes(arg.as_bytes()))
+            .collect();
+
+        Self { _c_strings: args, _temp_workdir: temp_workdir, views }
+    }
+
+    /// Decides if Centipede needs to be invoked based on the execution mode,
+    /// and constructs the appropriate arguments for it if so.
+    ///
+    /// Returns `Ok(Some(args))` if Centipede should be invoked, `Ok(None)` for `SmokeTest`,
+    /// or `Err` if argument generation fails.
+    pub fn from_execution_mode(
+        mode: &ExecutionMode,
+        options: &FuzzTestOptions,
+        current_test_name: Option<&str>,
+        list_file_path: Option<&Path>,
+    ) -> anyhow::Result<Option<Self>> {
+        let mode_opts = match mode {
+            ExecutionMode::SmokeTest => return Ok(None),
+            other => other,
+        };
+
+        let mut args = Vec::new();
+        let mut add_arg = |arg: String| -> anyhow::Result<()> {
+            args.push(CString::new(arg).context("while attempting to create CString arg")?);
+            Ok(())
+        };
+
+        // ==============================================================================
+        // 1. Common Base Arguments (Required across all Centipede executions)
+        // ==============================================================================
+        let argv0 = std::env::args().next().context("while attempting to get argv[0]")?;
+
+        if let Some(test_name) = current_test_name {
+            add_arg(format!("--binary={argv0} {test_name} --exact --nocapture"))?;
+            let normalized_test_name = test_name.replace("::", ".");
+            add_arg(format!("--test_name={normalized_test_name}"))?;
+        } else {
+            // We append the filter for fuzztests mod so that only fuzztests are executed and not unit tests.
+            add_arg(format!("--binary={argv0} __fuzztest_mod__ --nocapture"))?;
+        }
+
+        // Binary identifier is the same as the binary path (stripped of leading slash)
+        let binary_id = argv0.strip_prefix('/').unwrap_or(&argv0);
+        add_arg(format!("--fuzztest_binary_identifier={binary_id}"))?;
+
+        add_arg("--populate_binary_info=false".to_string())?;
+        add_arg("--fork_server=false".to_string())?;
+
+        add_arg(format!("--print_runner_log={}", options.print_subprocess_log))?;
+
+        // Add a dummy hash so as to avoid Centipede computing the hash of the binary.
+        add_arg("--binary_hash=DUMMY_HASH".to_string())?;
+
+        // ==============================================================================
+        // 2. Common Working Directory & Corpus Database Resolution
+        // ==============================================================================
+        let (opt_corpusdb, opt_workdir_root, opt_workdir) =
+            get_corpusdb_and_workdir_root_and_workdir(options)
+                .context("while attempting to resolve corpus and workdir options")?;
+
+        if let Some(corpus_db) = opt_corpusdb {
+            add_arg(format!("--fuzztest_corpus_database={corpus_db}"))?;
+        }
+
+        if let Some(workdir_root) = opt_workdir_root {
+            add_arg(format!("--fuzztest_workdir_root={workdir_root}"))?;
+        }
+
+        if let Some(temp_workdir) = &opt_workdir {
+            let workdir_path = temp_workdir
+                .path()
+                .to_str()
+                .context("while attempting to convert temp dir path to str")?
+                .to_string();
+            add_arg(format!("--workdir={workdir_path}"))?;
+        }
+
+        // ==============================================================================
+        // 3. Common Environment Variables Differential
+        // ==============================================================================
+        let env_diff = Self::default_env_diff();
+        add_arg(format!("--env_diff_for_binaries={}", env_diff.join(",")))?;
+
+        // ==============================================================================
+        // 4. Mode-Specific Arguments
+        // ==============================================================================
+        match mode_opts {
+            ExecutionMode::Fuzz(fuzz_opts) => {
+                match &fuzz_opts.fuzz_for {
+                    FuzzFor::Indefinitely => {
+                        // not specifying `--stop_after` means to run indefinitely.
+                    }
+                    FuzzFor::Duration(duration) => {
+                        if opt_corpusdb.is_some() {
+                            add_arg(format!("--fuzztest_time_limit_per_test={duration}"))?;
+                        } else {
+                            add_arg(format!("--stop_after={duration}"))?;
+                        }
+                    }
+                }
+                if let Some(jobs) = &fuzz_opts.jobs {
+                    add_arg(format!("--j={jobs}"))?;
+                }
+            }
+            ExecutionMode::ReplayCrash(replay_opts) => {
+                add_arg("--replay_crash".to_string())?;
+                add_arg(format!("--crash_id={}", replay_opts.replay_id))?;
+                add_arg("--exit_on_crash".to_string())?;
+            }
+            ExecutionMode::ReplayAllCrashes => {
+                let path = list_file_path
+                    .context("while attempting to get list_file path for ReplayAllCrashes")?;
+                add_arg("--list_crash_ids=true".to_string())?;
+                add_arg(format!("--list_crash_ids_file={}", path.display()))?;
+            }
+            ExecutionMode::ReplayCorpus(replay_corpus_opts) => {
+                let time_limit = match replay_corpus_opts.time_budget_type {
+                    TimeBudgetType::PerTest => replay_corpus_opts.replay_corpus_for,
+                    TimeBudgetType::Total => {
+                        let num_tests = inventory::iter::<FuzzTestRegistration>().count();
+                        if num_tests == 0 {
+                            replay_corpus_opts.replay_corpus_for
+                        } else {
+                            (*replay_corpus_opts.replay_corpus_for.as_ref() / (num_tests as u32))
+                                .into()
+                        }
+                    }
+                };
+                add_arg("--fuzztest_only_replay=true".to_string())?;
+                add_arg("--fuzztest_replay_coverage_inputs=true".to_string())?;
+                add_arg("--load_shards_only=true".to_string())?;
+                add_arg(format!("--fuzztest_time_limit_per_test={time_limit}"))?;
+            }
+            ExecutionMode::SmokeTest => unreachable!(),
+        }
+
+        Ok(Some(Self::new(args, opt_workdir)))
+    }
+
+    /// Generates the default environment variable diff list.
+    ///
+    /// This replicates the logic in `GetEnvDiffForBinaries` from
+    /// `fuzztest/internal/centipede_adaptor.cc`.
+    ///
+    /// When Centipede spawns the test binary as a subprocess, we do not want it to inherit
+    /// environment variables set by the test harness (like Blaze/Bazel). Inheriting these
+    /// could cause the subprocess to think it's running in a sharded environment, try to
+    /// write to restricted output files, or trigger other harness-specific behavior that
+    /// interferes with fuzzing.
+    fn default_env_diff() -> Vec<String> {
+        let mut env_diff = vec![
+            "-TEST_DIAGNOSTICS_OUTPUT_DIR".to_string(),
+            "-TEST_INFRASTRUCTURE_FAILURE_FILE".to_string(),
+            "-TEST_LOGSPLITTER_OUTPUT_FILE".to_string(),
+            "-TEST_PREMATURE_EXIT_FILE".to_string(),
+            "-TEST_RANDOM_SEED".to_string(),
+            "-TEST_RUN_NUMBER".to_string(),
+            "-TEST_SHARD_INDEX".to_string(),
+            "-TEST_SHARD_STATUS_FILE".to_string(),
+            "-TEST_TOTAL_SHARDS".to_string(),
+            "-TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR".to_string(),
+            "-TEST_UNDECLARED_OUTPUTS_DIR".to_string(),
+            "-TEST_WARNINGS_OUTPUT_FILE".to_string(),
+            "-GTEST_OUTPUT".to_string(),
+            "-XML_OUTPUT_FILE".to_string(),
+        ];
+
+        env_diff
+    }
+
+    /// Exposes the FFI-compatible argument views vector for C++ Centipede binding.
+    pub fn as_bytes_views(&self) -> engine_ffi::FuzzTestBytesViews {
+        engine_ffi::FuzzTestBytesViews { views: self.views.as_ptr(), count: self.views.len() }
+    }
+}
+
+/// Determines the `ExecutionAction` for the given test name by inspecting global options.
+pub fn determine_execution_action(current_test_name: Option<&str>) -> ExecutionAction {
+    determine_execution_action_internal(get_fuzztest_options(), current_test_name)
+}
+
+fn determine_execution_action_internal(
+    options: &FuzzTestOptions,
+    current_test_name: Option<&str>,
+) -> ExecutionAction {
+    options
+        .execution_mode()
+        .prepare_action(options, current_test_name)
+        .expect("failed to prepare execution action from fuzztest options")
+}
+
+fn get_corpusdb_and_workdir_root_and_workdir(
+    options: &FuzzTestOptions,
+) -> anyhow::Result<(Option<&str>, Option<&str>, Option<TempDir>)> {
+    let corpus_db = options.corpus_db.as_deref();
+    let workdir_root = options.workdir_root.as_deref();
+
+    if let Some(corpus_db) = corpus_db {
+        if let Some(workdir_root) = workdir_root {
+            Ok((Some(corpus_db), Some(workdir_root), None))
+        } else {
+            let temp_dir =
+                TempDir::new().context("while attempting to create temporary working directory")?;
+            Ok((Some(corpus_db), None, Some(temp_dir)))
+        }
+    } else {
+        if workdir_root.is_some() {
+            anyhow::bail!("NOT ALLOWED: workdir_root provided without corpus_db")
+        } else {
+            let temp_dir =
+                TempDir::new().context("while attempting to create temporary working directory")?;
+            Ok((None, None, Some(temp_dir)))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use googletest::prelude::*;
+    use std::ffi::OsString;
+
+    #[gtest]
+    fn test_fuzz_options_parsing_env() {
+        // SAFETY: Testing environment parsing in single-threaded context.
+        unsafe {
+            std::env::set_var("FUZZTEST_FUZZ_FOR", "5s");
+        }
+
+        let options = FuzzTestOptions::parse_from(std::iter::empty::<OsString>());
+
+        expect_true!(options.fuzz_for.is_some());
+        expect_that!(options.execution_mode(), matches_pattern!(ExecutionMode::Fuzz(_)));
+
+        // SAFETY: Cleaning up environment variables.
+        unsafe {
+            std::env::remove_var("FUZZTEST_FUZZ_FOR");
+        }
+    }
+
+    #[gtest]
+    fn test_fuzz_options_parsing_indefinite_env() {
+        // SAFETY: Testing environment parsing in single-threaded context.
+        unsafe {
+            std::env::set_var("FUZZTEST_FUZZ_FOR", "inf");
+        }
+
+        let options = FuzzTestOptions::parse_from(std::iter::empty::<OsString>());
+
+        expect_that!(options.fuzz_for, eq(Some(FuzzFor::Indefinitely)));
+        let mode = options.execution_mode();
+        let ExecutionMode::Fuzz(fuzz_opts) = mode else {
+            panic!("Expected ExecutionMode::Fuzz");
+        };
+        expect_that!(fuzz_opts.fuzz_for, eq(FuzzFor::Indefinitely));
+
+        // SAFETY: Cleaning up environment variables.
+        unsafe {
+            std::env::remove_var("FUZZTEST_FUZZ_FOR");
+        }
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_standalone_indefinite() {
+        let options =
+            FuzzTestOptions { fuzz_for: Some(FuzzFor::Indefinitely), ..Default::default() };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        // When running indefinitely, --stop_after must be omitted so Centipede runs until interrupted.
+        expect_false!(args_str.iter().any(|s| s.starts_with("--stop_after=")));
+        expect_true!(args_str.contains(&"--test_name=my_mod.my_test"));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_smoke_test() {
+        let options = FuzzTestOptions::default();
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+        assert!(matches!(action, ExecutionAction::SmokeTest));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_standalone() {
+        let expected_duration = "10s".parse().unwrap();
+        let options = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(expected_duration)),
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        expect_that!(args._c_strings.len(), eq(args.views.len()));
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        expect_true!(args_str
+            .iter()
+            .any(|s| s.starts_with("--binary=") && s.contains("my_mod::my_test --exact")));
+
+        expect_true!(args_str.contains(&"--stop_after=10s"));
+        expect_true!(args_str.contains(&"--test_name=my_mod.my_test"));
+        expect_true!(args_str.iter().any(|s| s.starts_with("--env_diff_for_binaries=")));
+
+        // Verify that a temporary workdir was created and passed as an argument.
+        expect_true!(args._temp_workdir.is_some());
+        let temp_workdir_path = args._temp_workdir.as_ref().unwrap().path().to_str().unwrap();
+        let expected_workdir_arg = format!("--workdir={}", temp_workdir_path);
+        expect_true!(args_str.contains(&expected_workdir_arg.as_str()));
+    }
+
+    #[gtest]
+    fn test_centipede_args_binary_identifier() {
+        let expected_duration = "1s".parse().unwrap();
+        let options = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(expected_duration)),
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        let argv0 = std::env::args().next().expect("get argv[0]");
+        let binary_id = argv0.strip_prefix('/').unwrap_or(&argv0);
+        let expected_binary_id_arg = format!("--fuzztest_binary_identifier={binary_id}");
+
+        expect_true!(args_str.contains(&expected_binary_id_arg.as_str()));
+    }
+
+    #[gtest]
+    fn test_centipede_args_jobs() {
+        let expected_duration = "1s".parse().expect("failed to parse duration");
+        let options_no_jobs = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(expected_duration)),
+            ..Default::default()
+        };
+        let action_no_jobs =
+            determine_execution_action_internal(&options_no_jobs, Some("my_mod::my_test"));
+        let ExecutionAction::Standalone(args_no_jobs) = action_no_jobs else {
+            panic!("Expected Standalone action");
+        };
+        let args_str_no_jobs: Vec<&str> =
+            args_no_jobs._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+        assert!(!args_str_no_jobs.iter().any(|s| s.starts_with("--j=")));
+
+        let options_with_jobs = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(expected_duration)),
+            jobs: Some(4),
+            ..Default::default()
+        };
+        let action_with_jobs =
+            determine_execution_action_internal(&options_with_jobs, Some("my_mod::my_test"));
+        let ExecutionAction::Standalone(args_with_jobs) = action_with_jobs else {
+            panic!("Expected Standalone action");
+        };
+        let args_str_with_jobs: Vec<&str> =
+            args_with_jobs._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+        assert!(args_str_with_jobs.contains(&"--j=4"));
+    }
+
+    #[gtest]
+    fn test_default_env_diff_set() {
+        let duration = "1s".parse().unwrap();
+        let options =
+            FuzzTestOptions { fuzz_for: Some(FuzzFor::Duration(duration)), ..Default::default() };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        let env_diff_arg = args_str
+            .iter()
+            .find(|s| s.starts_with("--env_diff_for_binaries="))
+            .expect("missing --env_diff_for_binaries arg");
+
+        expect_true!(env_diff_arg.contains("-TEST_SHARD_INDEX"));
+        expect_true!(env_diff_arg.contains("-XML_OUTPUT_FILE"));
+        expect_true!(env_diff_arg.contains("-GTEST_OUTPUT"));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_replay_crash_id() {
+        let options = FuzzTestOptions {
+            replay_id: Some("my_crash_123".to_string()),
+            corpus_db: Some("/tmp/corpus_db".to_string()),
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        expect_true!(args_str.contains(&"--replay_crash"));
+        expect_true!(args_str.contains(&"--crash_id=my_crash_123"));
+        expect_true!(args_str.contains(&"--fuzztest_corpus_database=/tmp/corpus_db"));
+        expect_true!(args_str.contains(&"--test_name=my_mod.my_test"));
+        expect_true!(args_str.iter().any(|s| s.starts_with("--workdir=")));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_replay_findings() {
+        let options = FuzzTestOptions {
+            replay_findings: true,
+            corpus_db: Some("/tmp/corpus_db".to_string()),
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::ReplayAllCrashes { args, list_file } = action else {
+            panic!("Expected ReplayAllCrashes action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        expect_true!(args_str.contains(&"--list_crash_ids=true"));
+        expect_true!(args_str
+            .contains(&format!("--list_crash_ids_file={}", list_file.path().display()).as_str()));
+        expect_true!(args_str.contains(&"--fuzztest_corpus_database=/tmp/corpus_db"));
+        expect_true!(args_str.iter().any(|s| s.starts_with("--workdir=")));
+        expect_true!(args_str.contains(&"--test_name=my_mod.my_test"));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_replay_corpus() {
+        let expected_duration = "10s".parse().expect("failed to parse duration");
+        let options = FuzzTestOptions {
+            replay_corpus_for: Some(expected_duration),
+            time_budget_type: TimeBudgetType::PerTest,
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        assert!(args_str
+            .iter()
+            .any(|s| s.starts_with("--binary=") && s.contains("my_mod::my_test --exact")));
+        assert!(args_str.contains(&"--fuzztest_only_replay=true"));
+        assert!(args_str.contains(&"--fuzztest_time_limit_per_test=10s"));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_replay_corpus_total_budget() {
+        let expected_duration = "10s".parse().expect("failed to parse duration");
+        let options = FuzzTestOptions {
+            replay_corpus_for: Some(expected_duration),
+            time_budget_type: TimeBudgetType::Total,
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        let num_tests = inventory::iter::<FuzzTestRegistration>().count();
+        let expected_limit = if num_tests == 0 {
+            expected_duration
+        } else {
+            (*expected_duration.as_ref() / (num_tests as u32)).into()
+        };
+        let expected_limit_str = format!("--fuzztest_time_limit_per_test={}", expected_limit);
+
+        assert!(args_str.contains(&expected_limit_str.as_str()));
+    }
+
+    #[gtest]
+    fn test_determine_execution_action_replay_corpus_no_test_name() {
+        let expected_duration = "10s".parse().expect("failed to parse duration");
+        let options = FuzzTestOptions {
+            replay_corpus_for: Some(expected_duration),
+            time_budget_type: TimeBudgetType::PerTest,
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, None);
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action");
+        };
+
+        let args_str: Vec<&str> =
+            args._c_strings.iter().map(|s| s.to_str().expect("invalid utf8")).collect();
+
+        assert!(args_str.iter().any(|s| s.contains("__fuzztest_mod__")));
+        assert!(args_str.contains(&"--fuzztest_only_replay=true"));
+        assert!(args_str.contains(&"--fuzztest_time_limit_per_test=10s"));
+        assert!(!args_str.iter().any(|s| s.starts_with("--test_name=")));
+    }
+
+    #[gtest]
+    fn test_get_corpusdb_and_workdir_default_creates_temp_workdir() -> Result<()> {
+        let options = FuzzTestOptions::default();
+        let (corpus_db, workdir_root, workdir) =
+            get_corpusdb_and_workdir_root_and_workdir(&options).or_fail()?;
+        expect_true!(corpus_db.is_none());
+        expect_true!(workdir_root.is_none());
+        expect_true!(workdir.is_some());
+        Ok(())
+    }
+
+    #[gtest]
+    fn test_get_corpusdb_and_workdir_succeeds_with_corpusdb_and_workdir_root() -> Result<()> {
+        let options = FuzzTestOptions {
+            corpus_db: Some("/tmp/db".to_string()),
+            workdir_root: Some("/tmp/root".to_string()),
+            ..Default::default()
+        };
+        let (corpus_db, workdir_root, workdir) =
+            get_corpusdb_and_workdir_root_and_workdir(&options).or_fail()?;
+        expect_that!(corpus_db, eq(Some("/tmp/db")));
+        expect_that!(workdir_root, eq(Some("/tmp/root")));
+        expect_true!(workdir.is_none());
+        Ok(())
+    }
+
+    #[gtest]
+    fn test_get_corpusdb_and_workdir_succeeds_with_corpusdb_only() -> Result<()> {
+        let options =
+            FuzzTestOptions { corpus_db: Some("/tmp/db".to_string()), ..Default::default() };
+        let (corpus_db, workdir_root, workdir) =
+            get_corpusdb_and_workdir_root_and_workdir(&options).or_fail()?;
+        expect_that!(corpus_db, eq(Some("/tmp/db")));
+        expect_true!(workdir_root.is_none());
+        expect_true!(workdir.is_some());
+        Ok(())
+    }
+
+    #[gtest]
+    fn test_replay_id_requires_corpus_db() {
+        // SAFETY: Testing environment parsing in single-threaded context.
+        unsafe {
+            std::env::set_var("FUZZTEST_REPLAY_ID", "my_crash_123");
+            std::env::remove_var("FUZZTEST_CORPUS_DB");
+        }
+
+        let result = FuzzTestOptions::try_parse_from(std::iter::empty::<OsString>());
+
+        // SAFETY: Cleaning up environment variables.
+        unsafe {
+            std::env::remove_var("FUZZTEST_REPLAY_ID");
+        }
+
+        let err = result.expect_err("parsing should fail when corpus_db is missing");
+        expect_that!(err.kind(), eq(clap::error::ErrorKind::MissingRequiredArgument));
+    }
+
+    #[gtest]
+    fn test_replay_id_with_corpus_db_succeeds() {
+        // SAFETY: Testing environment parsing in single-threaded context.
+        unsafe {
+            std::env::set_var("FUZZTEST_REPLAY_ID", "my_crash_123");
+            std::env::set_var("FUZZTEST_CORPUS_DB", "/tmp/corpus_db");
+        }
+
+        let result = FuzzTestOptions::try_parse_from(std::iter::empty::<OsString>());
+
+        // SAFETY: Cleaning up environment variables.
+        unsafe {
+            std::env::remove_var("FUZZTEST_REPLAY_ID");
+            std::env::remove_var("FUZZTEST_CORPUS_DB");
+        }
+
+        let options =
+            result.expect("parsing should succeed when both replay_id and corpus_db are present");
+        expect_that!(options.replay_id.as_deref(), eq(Some("my_crash_123")));
+        expect_that!(options.corpus_db.as_deref(), eq(Some("/tmp/corpus_db")));
+    }
+
+    #[gtest]
+    fn test_centipede_args_fuzz_for_duration_without_corpus_db() {
+        // When corpus_db is not provided, fuzzing for a fixed duration should pass --stop_after
+        // to Centipede so it stops fuzzing after the specified duration.
+        let duration = "1s".parse().expect("fixed test string should parse as duration");
+        let options = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(duration)),
+            corpus_db: None,
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action when fuzzing for duration");
+        };
+
+        let args_str: Vec<&str> = args
+            ._c_strings
+            .iter()
+            .map(|s| s.to_str().expect("args strings should be valid UTF-8"))
+            .collect();
+
+        expect_true!(args_str.contains(&"--stop_after=1s"));
+        expect_false!(args_str.iter().any(|s| s.starts_with("--fuzztest_time_limit_per_test=")));
+    }
+
+    #[gtest]
+    fn test_centipede_args_fuzz_for_duration_with_corpus_db() {
+        // When corpus_db is set, fuzzing for a duration should pass --fuzztest_time_limit_per_test
+        // instead of --stop_after, because Centipede uses time_limit_per_test when running against
+        // a corpus database.
+        let duration = "1s".parse().expect("fixed test string should parse as duration");
+        let options = FuzzTestOptions {
+            fuzz_for: Some(FuzzFor::Duration(duration)),
+            corpus_db: Some("/tmp/corpus_db".to_string()),
+            ..Default::default()
+        };
+        let action = determine_execution_action_internal(&options, Some("my_mod::my_test"));
+
+        let ExecutionAction::Standalone(args) = action else {
+            panic!("Expected Standalone action when fuzzing with corpus_db and duration");
+        };
+
+        let args_str: Vec<&str> = args
+            ._c_strings
+            .iter()
+            .map(|s| s.to_str().expect("args strings should be valid UTF-8"))
+            .collect();
+
+        expect_true!(args_str.contains(&"--fuzztest_time_limit_per_test=1s"));
+        expect_true!(args_str.contains(&"--fuzztest_corpus_database=/tmp/corpus_db"));
+        expect_false!(args_str.iter().any(|s| s.starts_with("--stop_after=")));
+    }
+}
diff --git a/rust/src/worker.rs b/rust/src/worker.rs
new file mode 100644
index 0000000..ba09d5e
--- /dev/null
+++ b/rust/src/worker.rs
@@ -0,0 +1,769 @@
+use super::domains::GenericCorpusValue;
+use super::internal::{BoxedFuzzTest, FuzzTest};
+use super::options::{self, CentipedeArgs, ExecutionAction};
+use ::engine::engine_ffi;
+use ::engine::{
+    BytesSink, CoverageDomainRegistry, DiagnosticSink, ExecuteContext, FeedbackSink, InputSink,
+};
+use spin::Mutex;
+use std::ffi::CString;
+use std::path::Path;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::LazyLock;
+
+/// The DiagnosticSink provided by the engine while creating the adapter.
+///
+/// Storing the `DiagnosticSink` in this global is necessary because C death callbacks (e.g.,
+/// sanitizer traps in `crash_handler.rs`) do not have access to the adapter instance and must rely
+/// on a global lookup to report crashes.
+static DIAGNOSTIC_SINK: Mutex<Option<DiagnosticSink>> = Mutex::new(None);
+
+/// A global execution context token.
+///
+/// This is set to `Some(ExecuteContext)` when the fuzz test is currently executing
+/// (inside the `execute` method of `RustFuzzTestAdapter`) and `None` otherwise.
+///
+/// The inner ExecuteContext is used as a witness token to prove to the fuzzing engine that findings
+/// are being emitted during the execution of a test case.
+/// A global is necessary because C death callbacks (e.g. sanitizer traps in `crash_handler.rs`) do
+/// not have access to the adapter instance.
+static EXECUTE_CONTEXT: Mutex<Option<ExecuteContext>> = Mutex::new(None);
+
+/// Sets the global DiagnosticSink.
+pub(crate) fn set_diagnostic_sink(sink: DiagnosticSink) {
+    let mut guard = DIAGNOSTIC_SINK.lock();
+    *guard = Some(sink);
+}
+
+/// Clears the global DiagnosticSink, setting it to None.
+pub(crate) fn clear_diagnostic_sink() {
+    let mut guard = DIAGNOSTIC_SINK.lock();
+    *guard = None;
+}
+
+/// Emits an error into the DiagnosticSink if the DiagnosticSink is set.
+/// This function blocks till it can get the lock on the global DiagnosticSink and is not
+/// signal-safe.
+pub(crate) fn emit_error(message: &str) {
+    DIAGNOSTIC_SINK.lock().as_ref().map(|sink| sink.emit_error(message));
+}
+
+/// Emits a finding into the DiagnosticSink if the DiagnosticSink is set.
+/// This function blocks till it can get the lock on the global DiagnosticSink and is not
+/// signal-safe. Call `try_emit_finding` from a signal handler instead.
+pub(crate) fn emit_finding(description: &str, signature: &str) {
+    let guard = EXECUTE_CONTEXT.lock();
+    let token =
+        guard.as_ref().expect("emit_finding should only be called when a test is executing");
+    DIAGNOSTIC_SINK
+        .lock()
+        .as_ref()
+        .expect("diagnostic sink should be present when a test is executing")
+        .emit_finding(token, description, signature);
+}
+
+/// Emits a finding into the DiagnosticSink if the DiagnosticSink is set, and we are in the Execute
+/// callback context. It only tries once to get the lock. The return value indicates if the finding
+/// was successfully emitted.
+///
+/// This function return false if:
+/// - it could not get the lock on DiagnosticSink.
+/// - it got the lock but the global DiagnosticSink was not set.
+/// - diagnostic sink was set but the test was not executing.
+#[allow(dead_code)]
+pub(crate) fn try_emit_finding(description: &str, signature: &str) -> bool {
+    let Some(diagnostic_guard) = DIAGNOSTIC_SINK.try_lock() else {
+        return false;
+    };
+    let Some(sink) = diagnostic_guard.as_ref() else {
+        return false;
+    };
+    let Some(execution_guard) = EXECUTE_CONTEXT.try_lock() else {
+        return false;
+    };
+    let Some(token) = execution_guard.as_ref() else {
+        return false;
+    };
+    sink.emit_finding(token, description, signature);
+    return true;
+}
+
+// We double-box the input because `GenericCorpusValue` is a fat pointer (`Box<dyn Any>`),
+// which cannot be directly represented as a single `usize` in `FuzzTestInputHandle` for FFI.
+// By boxing it again, we get a thin pointer (`Box<Box<dyn Any>>`) that can be safely cast
+// to `usize`.
+// The memory is reclaimed when the engine calls `free_input`, which reconstructs the outer
+// box using `Box::from_raw` and drops it, thereby dropping the inner box and the value.
+fn pack_input(input: GenericCorpusValue) -> engine_ffi::FuzzTestInputHandle {
+    let ptr = Box::into_raw(Box::new(input));
+    engine_ffi::FuzzTestInputHandle(ptr as usize)
+}
+
+/// A guard that manages the global `EXECUTE_CONTEXT` state, setting it to `Some` on creation,
+/// and resetting to `None` on drop.
+#[must_use = "the execution guard must be held for the duration of the test execution to record findings and crashes"]
+struct ExecutionGuard;
+
+impl ExecutionGuard {
+    /// Enters the execution context by setting `EXECUTE_CONTEXT`.
+    ///
+    /// # Safety
+    /// The caller must ensure we are in a valid state to create an `ExecuteContext`.
+    unsafe fn enter() -> Self {
+        *EXECUTE_CONTEXT.lock() = Some(unsafe { ExecuteContext::new() });
+        Self
+    }
+}
+
+impl Drop for ExecutionGuard {
+    fn drop(&mut self) {
+        *EXECUTE_CONTEXT.lock() = None;
+    }
+}
+
+pub struct RustFuzzTestAdapter {
+    fuzz_test: BoxedFuzzTest,
+}
+
+impl RustFuzzTestAdapter {
+    pub fn set_up_coverage_domains(&self, registry: &mut CoverageDomainRegistry) {
+        registry.set_up_sancov_domains();
+    }
+
+    pub fn get_preset_seed_inputs(&self, _sink: &mut InputSink) {
+        // TODO(the-shank): implement this once the macro has support for specifying preset seed
+        // inputs
+    }
+
+    pub fn get_random_seed_input(&self, sink: &mut InputSink) {
+        match self.fuzz_test.domains().init(&mut rand::rng()) {
+            Ok(val) => {
+                sink.emit(pack_input(val));
+            }
+            Err(e) => {
+                emit_error(&format!("Failed to initialize random seed: {:?}", e));
+            }
+        }
+    }
+
+    pub fn mutate(&self, origin: &GenericCorpusValue, shrink: bool, sink: &mut InputSink) {
+        let mut mutant = origin.clone();
+
+        if let Err(e) = self.fuzz_test.domains().mutate(&mut mutant, &mut rand::rng(), shrink) {
+            emit_error(&format!("Failed to mutate: {:?}", e));
+            return;
+        }
+
+        sink.emit(pack_input(mutant));
+    }
+
+    pub fn cross_over(
+        &self,
+        origin: &GenericCorpusValue,
+        _other: &GenericCorpusValue,
+        sink: &mut InputSink,
+    ) {
+        // TODO(the-shank): implement cross_over. Currently we are just calling mutate.
+        self.mutate(origin, false, sink);
+    }
+
+    pub fn execute(&self, input: &GenericCorpusValue, sink: &mut FeedbackSink) {
+        // TODO(the-shank): modify this in order to support persistent mode and batch execution.
+        static CLEAR_STARTUP_COVERAGE: AtomicBool = AtomicBool::new(true);
+        coverage::prepare_coverage(CLEAR_STARTUP_COVERAGE.swap(false, Ordering::AcqRel));
+
+        // SAFETY: We are currently in the `execute` callback of `RustFuzzTestAdapter`.
+        let _guard = unsafe { ExecutionGuard::enter() };
+
+        let result = self.fuzz_test.execute(input);
+
+        coverage::post_process_coverage(false);
+
+        sink.emit_sancov_features();
+
+        if !result {
+            // TODO(the-shank): the signature should be different for different panics. Currently,
+            // all test failures due to panics are reported with the same signature.
+            emit_finding("Property function ran but crashed.", "Unwinding panic");
+        }
+    }
+
+    pub fn serialize_input_content(&self, input: &GenericCorpusValue, sink: &mut BytesSink) {
+        match self.fuzz_test.domains().serialize_corpus(input) {
+            Ok(serialized) => {
+                sink.emit(&serialized);
+            }
+            Err(e) => {
+                emit_error(&format!("Failed to serialize input: {:?}", e));
+            }
+        }
+    }
+
+    pub fn deserialize_input_content(&self, content: &[u8], sink: &mut InputSink) {
+        match self.fuzz_test.domains().parse_corpus(content) {
+            Ok(val) => {
+                sink.emit(pack_input(val));
+            }
+            Err(e) => {
+                emit_error(&format!("Failed to deserialize input: {:?}", e));
+            }
+        }
+    }
+
+    pub fn serialize_input_metadata(&self, _input: &GenericCorpusValue, _sink: &mut BytesSink) {
+        // TODO(the-shank): to be implemented
+    }
+
+    pub fn update_input_metadata(&self, _metadata: &[u8], _input: &mut GenericCorpusValue) {
+        // TODO(the-shank): to be implemented
+    }
+
+    pub fn free_input(&self, input: engine_ffi::FuzzTestInputHandle) {
+        if input.0 != 0 {
+            // SAFETY: The engine guarantees `input` was created by `deserialize_input_content_callback`
+            // (or `emit` in `InputSink`) and has not been freed yet.
+            unsafe {
+                let _ = Box::from_raw(input.0 as *mut GenericCorpusValue);
+            }
+        }
+    }
+}
+
+pub struct RustFuzzTestAdapterManager {
+    pub test_name: &'static str,
+    pub fuzz_test_factory: fn() -> BoxedFuzzTest,
+}
+
+impl RustFuzzTestAdapterManager {
+    pub fn get_binary_id(&self, sink: &mut BytesSink) {
+        static ARGV0: LazyLock<CString> = LazyLock::new(|| {
+            CString::new(
+                Path::new(&std::env::args().nth(0).unwrap())
+                    .file_name()
+                    .and_then(|f| f.to_str())
+                    .unwrap_or(""),
+            )
+            .expect("argv[0] should not contain null bytes")
+        });
+        sink.emit(ARGV0.as_bytes());
+    }
+
+    // Replaces "::" with "." to avoid parsing issues in Centipede. Centipede uses ":" as a
+    // separator in CENTIPEDE_RUNNER_FLAGS and its parser replaces all ":" with "\0", which would
+    // truncate Rust paths.
+    pub fn get_test_name(&self, sink: &mut BytesSink) {
+        let name = self.test_name.replace("::", ".");
+        sink.emit(name.as_bytes());
+    }
+
+    pub fn construct_adapter(&self) -> RustFuzzTestAdapter {
+        let fuzz_test = (self.fuzz_test_factory)();
+        RustFuzzTestAdapter { fuzz_test }
+    }
+
+    pub fn construct_fuzz_test(&self) -> BoxedFuzzTest {
+        (self.fuzz_test_factory)()
+    }
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapterManager` passed during initialization.
+/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration
+///   of this call.
+pub unsafe extern "C" fn get_binary_id_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterManagerCtx,
+    sink: *const engine_ffi::FuzzTestBytesSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapterManager`
+    // passed during initialization.
+    let manager = unsafe { &*(ctx as *const RustFuzzTestAdapterManager) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to a `FuzzTestBytesSink`
+    // whose lifetime extends for the duration of this call.
+    let mut safe_sink = unsafe { BytesSink::from_raw(sink) };
+    manager.get_binary_id(&mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapterManager` passed during initialization.
+/// * `sink` is a valid pointer to a `FuzzTestBytesSink` whose lifetime extends for the duration
+///   of this call.
+pub unsafe extern "C" fn get_test_name_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterManagerCtx,
+    sink: *const engine_ffi::FuzzTestBytesSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapterManager`
+    // passed during initialization.
+    let manager = unsafe { &*(ctx as *const RustFuzzTestAdapterManager) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to a `FuzzTestBytesSink`
+    // whose lifetime extends for the duration of this call.
+    let mut safe_sink = unsafe { BytesSink::from_raw(sink) };
+    manager.get_test_name(&mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapterManager` passed during initialization.
+/// * `diagnostic_sink` is a valid pointer to a `FuzzTestDiagnosticSink` whose lifetime extends
+///   until `FreeCtx` is called on the adapter.
+/// * `adapter_out` is a valid pointer to write the output `FuzzTestAdapter`.
+pub unsafe extern "C" fn construct_adapter_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterManagerCtx,
+    diagnostic_sink: *const engine_ffi::FuzzTestDiagnosticSink,
+    adapter_out: *mut engine_ffi::FuzzTestAdapter,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapterManager`
+    // passed during initialization.
+    let manager = unsafe { &*(ctx as *const RustFuzzTestAdapterManager) };
+
+    // SAFETY: The engine guarantees `diagnostic_sink` is a valid pointer to a `FuzzTestDiagnosticSink`
+    // whose lifetime extends until `FreeCtx` is called on the adapter.
+    let safe_sink = unsafe { DiagnosticSink::from_raw(diagnostic_sink) };
+
+    set_diagnostic_sink(safe_sink);
+
+    // NOTE: `safe_sink` is not passed to `construct_adapter` or stored in `RustFuzzTestAdapter`.
+    // Instead, it is maintained in the global `DIAGNOSTIC_SINK` mutex via `set_diagnostic_sink`.
+    // This is necessary because C death callbacks (e.g., sanitizer traps in `crash_handler.rs`) do not
+    // have access to the adapter `self` pointer and must rely on a global lookup to report crashes.
+    let adapter = manager.construct_adapter();
+    let boxed_adapter = Box::new(adapter);
+    // SAFETY: The engine guarantees `adapter_out` is a valid pointer to write the output adapter.
+    // The returned raw pointer `ctx` will be managed and eventually freed by `free_ctx_callback`.
+    unsafe {
+        *adapter_out = engine_ffi::FuzzTestAdapter {
+            ctx: Box::into_raw(boxed_adapter) as *mut engine_ffi::FuzzTestAdapterCtx,
+            set_up_coverage_domains: Some(set_up_coverage_domains_callback),
+            get_preset_seed_inputs: Some(get_preset_seed_inputs_callback),
+            get_random_seed_input: Some(get_random_seed_input_callback),
+            mutate: Some(mutate_callback),
+            cross_over: Some(cross_over_callback),
+            execute: Some(execute_callback),
+            serialize_input_content: Some(serialize_input_content_callback),
+            deserialize_input_content: Some(deserialize_input_content_callback),
+            serialize_input_metadata: Some(serialize_input_metadata_callback),
+            update_input_metadata: Some(update_input_metadata_callback),
+            free_input: Some(free_input_callback),
+            free_ctx: Some(free_ctx_callback),
+        };
+    }
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `registry` is a valid pointer to `FuzzTestCoverageDomainRegistry`.
+pub unsafe extern "C" fn set_up_coverage_domains_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    registry: *const engine_ffi::FuzzTestCoverageDomainRegistry,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `registry` is a valid pointer to `FuzzTestCoverageDomainRegistry`.
+    let mut registry = unsafe { CoverageDomainRegistry::from_raw(registry) };
+    adapter.set_up_coverage_domains(&mut registry);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `sink` is a valid pointer to `FuzzTestInputSink`.
+pub unsafe extern "C" fn get_preset_seed_inputs_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    sink: *const engine_ffi::FuzzTestInputSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestInputSink`.
+    let mut safe_sink = unsafe { InputSink::from_raw(sink) };
+    adapter.get_preset_seed_inputs(&mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `sink` is a valid pointer to `FuzzTestInputSink`.
+pub unsafe extern "C" fn get_random_seed_input_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    sink: *const engine_ffi::FuzzTestInputSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestInputSink`.
+    let mut safe_sink = unsafe { InputSink::from_raw(sink) };
+    adapter.get_random_seed_input(&mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `origin` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `sink` is a valid pointer to `FuzzTestInputSink`.
+pub unsafe extern "C" fn mutate_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    origin: engine_ffi::FuzzTestInputHandle,
+    shrink: std::ffi::c_int,
+    sink: *const engine_ffi::FuzzTestInputSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `origin` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let origin_ref = unsafe { &*(origin.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestInputSink`.
+    let mut safe_sink = unsafe { InputSink::from_raw(sink) };
+    adapter.mutate(origin_ref, shrink != 0, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `origin` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `other` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `sink` is a valid pointer to `FuzzTestInputSink`.
+pub unsafe extern "C" fn cross_over_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    origin: engine_ffi::FuzzTestInputHandle,
+    other: engine_ffi::FuzzTestInputHandle,
+    sink: *const engine_ffi::FuzzTestInputSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `origin` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let origin_ref = unsafe { &*(origin.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `other` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let other_ref = unsafe { &*(other.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestInputSink`.
+    let mut safe_sink = unsafe { InputSink::from_raw(sink) };
+    adapter.cross_over(origin_ref, other_ref, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `sink` is a valid pointer to `FuzzTestFeedbackSink`.
+pub unsafe extern "C" fn execute_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    input: engine_ffi::FuzzTestInputHandle,
+    sink: *const engine_ffi::FuzzTestFeedbackSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `input` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let input_ref = unsafe { &*(input.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestFeedbackSink`.
+    let mut safe_sink = unsafe { FeedbackSink::from_raw(sink) };
+
+    adapter.execute(input_ref, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `sink` is a valid pointer to `FuzzTestBytesSink`.
+pub unsafe extern "C" fn serialize_input_content_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    input: engine_ffi::FuzzTestInputHandle,
+    sink: *const engine_ffi::FuzzTestBytesSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `input` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let input_ref = unsafe { &*(input.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestBytesSink`.
+    let mut safe_sink = unsafe { BytesSink::from_raw(sink) };
+    adapter.serialize_input_content(input_ref, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `content` is a valid pointer to `FuzzTestBytesView` containing serialized input content.
+/// * `sink` is a valid pointer to `FuzzTestInputSink`.
+pub unsafe extern "C" fn deserialize_input_content_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    content: *const engine_ffi::FuzzTestBytesView,
+    sink: *const engine_ffi::FuzzTestInputSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `content` is a valid pointer to `FuzzTestBytesView`
+    // containing serialized input content.
+    let bytes = unsafe { &*(*content).to_bytes() };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestInputSink`.
+    let mut safe_sink = unsafe { InputSink::from_raw(sink) };
+    adapter.deserialize_input_content(bytes, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework.
+/// * `sink` is a valid pointer to `FuzzTestBytesSink`.
+pub unsafe extern "C" fn serialize_input_metadata_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    input: engine_ffi::FuzzTestInputHandle,
+    sink: *const engine_ffi::FuzzTestBytesSink,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `input` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework.
+    let input_ref = unsafe { &*(input.0 as *const GenericCorpusValue) };
+    // SAFETY: The engine guarantees `sink` is a valid pointer to `FuzzTestBytesSink`.
+    let mut safe_sink = unsafe { BytesSink::from_raw(sink) };
+    adapter.serialize_input_metadata(input_ref, &mut safe_sink);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `metadata` is a valid pointer to `FuzzTestBytesView` containing serialized input metadata.
+/// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework, and the engine guarantees exclusive access to it for the call duration.
+pub unsafe extern "C" fn update_input_metadata_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    metadata: *const engine_ffi::FuzzTestBytesView,
+    input: engine_ffi::FuzzTestInputHandle,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    // SAFETY: The engine guarantees `metadata` is a valid pointer to `FuzzTestBytesView`
+    // containing serialized input metadata.
+    let bytes = unsafe { &*(*metadata).to_bytes() };
+    // SAFETY: The engine guarantees `input` is a valid `FuzzTestInputHandle` pointing to
+    // a heap-allocated `GenericCorpusValue` managed by the framework, and provides exclusive
+    // access to it.
+    let input_ref = unsafe { &mut *(input.0 as *mut GenericCorpusValue) };
+    adapter.update_input_metadata(bytes, input_ref);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+/// * `input` is a valid `FuzzTestInputHandle` pointing to a heap-allocated `GenericCorpusValue`
+///   managed by the framework that has not been freed yet.
+pub unsafe extern "C" fn free_input_callback(
+    ctx: *mut engine_ffi::FuzzTestAdapterCtx,
+    input: engine_ffi::FuzzTestInputHandle,
+) {
+    // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+    // created by `construct_adapter_callback`.
+    let adapter = unsafe { &*(ctx as *const RustFuzzTestAdapter) };
+    adapter.free_input(input);
+}
+
+/// # Safety
+///
+/// The caller must ensure that:
+/// * `ctx` is a valid pointer to the `RustFuzzTestAdapter` created by `construct_adapter_callback`.
+pub unsafe extern "C" fn free_ctx_callback(ctx: *mut engine_ffi::FuzzTestAdapterCtx) {
+    if !ctx.is_null() {
+        // SAFETY: The engine guarantees `ctx` is a valid pointer to the `RustFuzzTestAdapter`
+        // created by `construct_adapter_callback`.
+        let ptr = ctx as *mut RustFuzzTestAdapter;
+        drop(unsafe { Box::from_raw(ptr) });
+
+        clear_diagnostic_sink();
+    }
+}
+
+pub fn run_smoke_test(fuzztest: &dyn FuzzTest) {
+    let start_time = std::time::Instant::now();
+
+    // TODO(the-shank): these should be configurable externally.
+    let smoke_test_duration = std::time::Duration::from_secs(1);
+    let only_shrink = false;
+
+    // TODO(the-shank): the rng seed should be configurable
+    let mut rng = rand::rng();
+
+    let mut generic_corpus_value = fuzztest
+        .domains()
+        .init(&mut rng)
+        .expect("domain initialization should succeed to provide an initial corpus value");
+
+    let result = fuzztest.execute(&generic_corpus_value);
+    // DISCUSS: probably need a more "googletest" approach to handling the result here?
+    assert!(result);
+
+    while start_time.elapsed() < smoke_test_duration {
+        fuzztest
+            .domains()
+            .mutate(&mut generic_corpus_value, &mut rng, only_shrink)
+            .expect("domain mutation should succeed");
+        let result = fuzztest.execute(&generic_corpus_value);
+        // DISCUSS: probably need a more "googletest" approach to handling the result here?
+        assert!(result);
+    }
+}
+
+pub enum WorkerStatus {
+    Success,
+    Failure,
+}
+
+/// Processes and executes a fuzz test using the provided [`RustFuzzTestAdapterManager`].
+///
+/// This function serves as the primary entry point for running a fuzz test. It manages test
+/// execution across two operational modes:
+///
+/// 1. Worker Mode: Registers signal/sanitizer crash handlers and attempts to hand off execution to
+///    the external fuzzing engine (e.g., Centipede) via [`maybe_run_as_worker`].
+///    - If the binary was spawned as a worker process by the fuzzing engine, control remains in the
+///      engine loop until complete.
+///    - Returns cleanly on [`WorkerStatus::Success`], or panics on [`WorkerStatus::Failure`] to
+///      signal test failure to the harness.
+/// 2. Smoke Test Mode: If worker mode is not active (e.g., during standard `blaze test` or
+///    `cargo test` unit test runs), falls back to executing a short local smoke test using sample
+///    inputs and mutation iterations to verify property function sanity.
+pub fn process(manager: RustFuzzTestAdapterManager) {
+    super::crash_handler::register_crash_handler();
+
+    // box it to get a stable heap address.
+    let manager = Box::new(manager);
+
+    if let Some(status) = maybe_run_as_worker(&manager) {
+        match status {
+            WorkerStatus::Success => {
+                // do nothing, the harness would continue to the next test
+                return;
+            }
+            WorkerStatus::Failure => {
+                std::process::exit(1);
+            }
+        }
+    }
+
+    // worker mode was not run -- determine what to do next.
+    match options::determine_execution_action(Some(manager.test_name)) {
+        ExecutionAction::Standalone(centipede_args) => {
+            let status = run_standalone_mode(&manager, centipede_args);
+            if status == engine_ffi::FuzzTestControllerStatus::Failure {
+                panic!("FuzzTest controller reported failure");
+            }
+        }
+        ExecutionAction::ReplayAllCrashes { args, list_file } => {
+            let status = run_standalone_mode(&manager, args);
+            if status == engine_ffi::FuzzTestControllerStatus::Failure {
+                panic!("FuzzTest controller reported failure");
+            }
+
+            // Now read the file and replay each crash
+            if let Ok(contents) = std::fs::read_to_string(list_file.path()) {
+                let options = options::get_fuzztest_options();
+                for crash_id in contents.lines() {
+                    let crash_id = crash_id.trim();
+                    if crash_id.is_empty() {
+                        continue;
+                    }
+                    let replay_mode =
+                        options::ExecutionMode::ReplayCrash(options::ReplayCrashOptions {
+                            replay_id: crash_id.to_string(),
+                        });
+                    if let Ok(Some(replay_args)) = CentipedeArgs::from_execution_mode(
+                        &replay_mode,
+                        options,
+                        Some(manager.test_name),
+                        None,
+                    ) {
+                        // We ignore the result here because replaying a crash is expected to fail
+                        // (report failure). We want to continue replaying other crashes.
+                        let _ = run_standalone_mode(&manager, replay_args);
+                    }
+                }
+            }
+        }
+        ExecutionAction::SmokeTest => {
+            let fuzz_test = manager.construct_fuzz_test();
+            run_smoke_test(fuzz_test.as_ref());
+        }
+    }
+}
+
+fn make_ffi_manager(manager: &RustFuzzTestAdapterManager) -> engine_ffi::FuzzTestAdapterManager {
+    let ctx =
+        manager as *const RustFuzzTestAdapterManager as *mut engine_ffi::FuzzTestAdapterManagerCtx;
+
+    engine_ffi::FuzzTestAdapterManager {
+        ctx,
+        get_binary_id: Some(get_binary_id_callback),
+        get_test_name: Some(get_test_name_callback),
+        construct_adapter: Some(construct_adapter_callback),
+    }
+}
+
+/// Attempts to run the fuzz test in Centipede worker mode using the FFI engine interface.
+///
+/// This function constructs a C-compatible [`engine_ffi::FuzzTestAdapterManager`] wrapping
+/// the given `manager` with required callback function pointers (`get_binary_id_callback`,
+/// `get_test_name_callback`, `construct_adapter_callback`), and invokes
+/// [`engine_ffi::FuzzTestWorkerMaybeRun`].
+///
+/// # Returns
+/// - `Some(WorkerStatus::Success)`: The process ran in worker mode and completed successfully.
+/// - `Some(WorkerStatus::Failure)`: The process ran in worker mode and encountered a failure.
+/// - `None`: Worker mode was not requested (`kFuzzTestWorkerNotRequired`). The caller should fall
+///   back to standalone smoke-test execution.
+fn maybe_run_as_worker(manager: &RustFuzzTestAdapterManager) -> Option<WorkerStatus> {
+    let ffi_manager = make_ffi_manager(manager);
+
+    // SAFETY: `manager` is a valid heap-allocated `RustFuzzTestAdapterManager`,
+    // and `ffi_manager` contains valid C-compatible function pointer callbacks.
+    let status = unsafe { engine_ffi::FuzzTestWorkerMaybeRun(&ffi_manager) };
+
+    match status {
+        engine_ffi::FuzzTestWorkerStatus::Success => Some(WorkerStatus::Success),
+        engine_ffi::FuzzTestWorkerStatus::Failure => Some(WorkerStatus::Failure),
+        engine_ffi::FuzzTestWorkerStatus::NotRequired => None,
+    }
+}
+
+fn run_standalone_mode(
+    manager: &RustFuzzTestAdapterManager,
+    centipede_args: CentipedeArgs,
+) -> engine_ffi::FuzzTestControllerStatus {
+    let ffi_manager = make_ffi_manager(manager);
+
+    // SAFETY: `ffi_manager` wraps `manager` which is guaranteed to be alive. `centipede_args` is
+    // alive until the end of this function, since we have the ownership, ensuring that the
+    // pointers passed to `FuzzTestControllerRun` remain valid.
+    unsafe { engine_ffi::FuzzTestControllerRun(&ffi_manager, &centipede_args.as_bytes_views()) }
+}
diff --git a/rust/tests/macro_compiles.rs b/rust/tests/macro_compiles.rs
new file mode 100644
index 0000000..a294458
--- /dev/null
+++ b/rust/tests/macro_compiles.rs
@@ -0,0 +1,10 @@
+use fuzztest::domains::arbitrary::Arbitrary;
+use fuzztest::fuzztest;
+
+#[fuzztest(_a = Arbitrary::<i32>::default())]
+fn fuzztest_macro_compiles(_a: i32) {}
+
+#[fuzztest(_a = Arbitrary::<i32>::default(), _b = Arbitrary::<i32>::default())]
+fn fuzztest_macro_compiles_with_two_args(_a: i32, _b: i32) {}
+
+fn main() {}
diff --git a/rust/tests/trybuild.rs b/rust/tests/trybuild.rs
new file mode 100644
index 0000000..c2d9ebd
--- /dev/null
+++ b/rust/tests/trybuild.rs
@@ -0,0 +1,5 @@
+#[test]
+fn fuzztest() {
+    let t = trybuild::TestCases::new();
+    t.pass("tests/macro_compiles.rs");
+}