Add rustfmt checks

This will run rustfmt on all diffed rust files

Test: check_rustfmt and manual testing
Bug: 153652717
Change-Id: I990f22b92b976ad9b5d05304c66151b70102fb6f
diff --git a/README.md b/README.md
index c093776..83572ac 100644
--- a/README.md
+++ b/README.md
@@ -190,6 +190,7 @@
 * `pylint`: Alias of `pylint2`.  Will change to `pylint3` by end of 2019.
 * `pylint2`: Run Python code through `pylint` using Python 2.
 * `pylint3`: Run Python code through `pylint` using Python 3.
+* `rustfmt`: Run Rust code through `rustfmt`.
 * `xmllint`: Run XML code through `xmllint`.
 * `android_test_mapping_format`: Validate TEST_MAPPING files in Android source
   code. Refer to go/test-mapping for more details.
@@ -239,6 +240,7 @@
 * `google-java-format`: used for the `google_java_format` builtin hook.
 * `google-java-format-diff`: used for the `google_java_format` builtin hook.
 * `pylint`: used for the `pylint` builtin hook.
+* `rustfmt`: used for the `rustfmt` builtin hook.
 * `android-test-mapping-format`: used for the `android_test_mapping_format`
   builtin hook.
 
diff --git a/rh/hooks.py b/rh/hooks.py
index 5422494..21be3cc 100644
--- a/rh/hooks.py
+++ b/rh/hooks.py
@@ -730,6 +730,17 @@
                          options=options)
 
 
+def check_rustfmt(project, commit, desc, diff, options=None):
+    """Run "rustfmt --check" on diffed rust files"""
+    filtered = _filter_diff(diff, [r'\.rs$'])
+    if not filtered:
+        return None
+
+    rustfmt = options.tool_path('rustfmt')
+    cmd = [rustfmt] + options.args(('--check', '${PREUPLOAD_FILES}',), filtered)
+    return _check_cmd('rustfmt', project, commit, cmd)
+
+
 def check_xmllint(project, commit, _desc, diff, options=None):
     """Run xmllint."""
     # XXX: Should we drop most of these and probe for <?xml> tags?
@@ -808,6 +819,7 @@
     'pylint': check_pylint2,
     'pylint2': check_pylint2,
     'pylint3': check_pylint3,
+    'rustfmt': check_rustfmt,
     'xmllint': check_xmllint,
 }
 
@@ -824,4 +836,5 @@
     'google-java-format': 'google-java-format',
     'google-java-format-diff': 'google-java-format-diff.py',
     'pylint': 'pylint',
+    'rustfmt': 'rustfmt',
 }
diff --git a/rh/hooks_unittest.py b/rh/hooks_unittest.py
index 754a16e..0442f4e 100755
--- a/rh/hooks_unittest.py
+++ b/rh/hooks_unittest.py
@@ -617,6 +617,10 @@
         self._test_file_filter(mock_check, rh.hooks.check_pylint3,
                                ('foo.py',))
 
+    def test_rustfmt(self, mock_check, _mock_run):
+        self._test_file_filter(mock_check, rh.hooks.check_rustfmt,
+                               ('foo.rs',))
+
     def test_xmllint(self, mock_check, _mock_run):
         """Verify the xmllint builtin hook."""
         self._test_file_filter(mock_check, rh.hooks.check_xmllint,