diff --git a/WORKSPACE b/WORKSPACE
index 8fa3697f9..8bfe52c81 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -21,11 +21,13 @@ workspace(name = "vaticle_dependencies")
# Load @vaticle_dependencies #
################################
-# Load //build/rust
+# Load //builder/rust
load("//builder/rust:deps.bzl", rust_deps = "deps")
rust_deps()
-load("@rules_rust//rust:repositories.bzl", "rust_repositories")
-rust_repositories(version = "nightly", iso_date = "2021-07-01", edition="2018")
+
+load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")
+rules_rust_dependencies()
+rust_register_toolchains(edition = "2021", include_rustc_srcs = True)
# Load //builder/python
load("//builder/python:deps.bzl", python_deps = "deps")
diff --git a/builder/grpc/rust/BUILD b/builder/grpc/rust/BUILD
new file mode 100644
index 000000000..9593aecf4
--- /dev/null
+++ b/builder/grpc/rust/BUILD
@@ -0,0 +1,33 @@
+#
+# Copyright (C) 2022 Vaticle
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+load("@rules_rust//rust:defs.bzl", "rust_binary")
+load("@vaticle_dependencies//tool/checkstyle:rules.bzl", "checkstyle_test")
+
+rust_binary(
+ name = "compile",
+ srcs = ["compile.rs"],
+ deps = ["@vaticle_dependencies//library/crates:tonic_build"],
+ visibility = ["//visibility:public"]
+)
+
+checkstyle_test(
+ name = "checkstyle",
+ include = glob(["*"]),
+ license_type = "agpl-header",
+ size = "small",
+)
diff --git a/builder/grpc/rust/compile.bzl b/builder/grpc/rust/compile.bzl
new file mode 100644
index 000000000..16b57c54a
--- /dev/null
+++ b/builder/grpc/rust/compile.bzl
@@ -0,0 +1,62 @@
+#
+# Copyright (C) 2022 Vaticle
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+
+def _rust_tonic_compile_impl(ctx):
+ protos = [src[ProtoInfo].direct_sources[0] for src in ctx.attr.srcs]
+
+ inputs = ctx.attr.protoc.files.to_list() + protos
+ outputs = [ctx.actions.declare_file("{}.rs".format(package)) for package in ctx.attr.packages]
+
+ ctx.actions.run(
+ inputs = inputs,
+ outputs = outputs,
+ executable = ctx.executable._compile_script,
+ env = {
+ "OUT_DIR": outputs[0].dirname,
+ "PROTOC": ctx.attr.protoc.files.to_list()[0].path,
+ "PROTOS": ";".join([src.path for src in protos]),
+ "PROTOS_ROOT": ctx.attr.srcs[0][ProtoInfo].proto_source_root,
+ },
+ mnemonic = "RustTonicCompileAction"
+ )
+
+ return [DefaultInfo(files = depset(outputs))]
+
+rust_tonic_compile = rule(
+ implementation = _rust_tonic_compile_impl,
+ attrs = {
+ "srcs": attr.label_list(
+ allow_files = True,
+ mandatory = True,
+ doc = "The .proto source files."
+ ),
+ "packages": attr.string_list(
+ mandatory = True,
+ allow_empty = False,
+ doc = "The Protobuf package names. Each package name corresponds to a single output file."
+ ),
+ "protoc": attr.label(
+ default = "@com_google_protobuf//:protoc",
+ doc = "The protoc executable."
+ ),
+ "_compile_script": attr.label(
+ executable = True,
+ cfg = "host",
+ default = "@vaticle_dependencies//builder/grpc/rust:compile",
+ ),
+ }
+)
diff --git a/builder/grpc/rust/compile.rs b/builder/grpc/rust/compile.rs
new file mode 100644
index 000000000..ad8cddd8d
--- /dev/null
+++ b/builder/grpc/rust/compile.rs
@@ -0,0 +1,28 @@
+//
+// Copyright (C) 2022 Vaticle
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+//
+
+use std::env;
+
+fn main() -> std::io::Result<()> {
+ let protos_raw = env::var("PROTOS").expect("PROTOS environment variable is not set");
+ let protos: Vec<&str> = protos_raw.split(";").filter(|&str| !str.is_empty()).collect();
+
+ tonic_build::configure()
+ .compile(&protos, &[
+ env::var("PROTOS_ROOT").expect("PROTOS_ROOT environment variable is not set")
+ ])
+}