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()),
+ ]
+ );
+}