Also implement `MessageMatcher<T>` for `T: Copy`

This makes it possible to match views by value:

```rust
        expect_that!(
            response.clients(),
            unordered_elements_are![
                proto_eq(proto!(Client { name: "Alice" }).as_view()),
                proto_eq(proto!(Client { name: "Bob" }).as_view())
            ]
        );
```

where `clients()` return an iterator over `ClientView` values.

PiperOrigin-RevId: 692192744
diff --git a/rust/gtest_matchers_impl.rs b/rust/gtest_matchers_impl.rs
index 0dc833a..c52f98b 100644
--- a/rust/gtest_matchers_impl.rs
+++ b/rust/gtest_matchers_impl.rs
@@ -30,6 +30,22 @@
     }
 }
 
+impl<T> Matcher<T> for MessageMatcher<T>
+where
+    T: MatcherEq + Copy,
+{
+    fn matches(&self, actual: T) -> MatcherResult {
+        actual.matches(&self.expected).into()
+    }
+
+    fn describe(&self, matcher_result: MatcherResult) -> Description {
+        match matcher_result {
+            MatcherResult::Match => format!("is equal to {:?}", self.expected).into(),
+            MatcherResult::NoMatch => format!("is not equal to {:?}", self.expected).into(),
+        }
+    }
+}
+
 pub fn proto_eq<T: MatcherEq>(expected: T) -> MessageMatcher<T> {
     MessageMatcher { expected }
 }
diff --git a/rust/test/shared/gtest_matchers_test.rs b/rust/test/shared/gtest_matchers_test.rs
index a74add5..0cd09d2 100644
--- a/rust/test/shared/gtest_matchers_test.rs
+++ b/rust/test/shared/gtest_matchers_test.rs
@@ -11,7 +11,9 @@
 
 use googletest::prelude::*;
 use paste::paste;
+use protobuf::proto;
 use protobuf_gtest_matchers::proto_eq;
+use unittest_proto3_rust_proto::test_all_types::NestedMessage;
 use unittest_proto3_rust_proto::TestAllTypes as TestAllTypesProto3;
 use unittest_rust_proto::TestAllTypes;
 
@@ -52,3 +54,25 @@
 generate_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3));
 
 generate_not_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3));
+
+#[gtest]
+fn proto_eq_works_on_view() {
+    // This exercises the `impl<T> Matcher<T> for MessageMatcher<T>
+    // where T: MatcherEq + Copy` implementation.
+    let msg = proto!(TestAllTypesProto3 {
+        repeated_nested_message: [
+            NestedMessage { bb: 10 },
+            NestedMessage { bb: 20 },
+            NestedMessage { bb: 30 }
+        ]
+    });
+
+    expect_that!(
+        msg.repeated_nested_message(),
+        unordered_elements_are![
+            proto_eq(proto!(NestedMessage { bb: 10 }).as_view()),
+            proto_eq(proto!(NestedMessage { bb: 20 }).as_view()),
+            proto_eq(proto!(NestedMessage { bb: 30 }).as_view()),
+        ]
+    );
+}