Skip to content

Commit 4e763c4

Browse files
Googlercopybara-github
Googler
authored andcommitted
Relax trait bound restrictions for more flexible use of match_matrix.
This relaxes the earlier type constraint of requiring the `actual` collection to be `Copy` or `Debug`. The main reason this was done was to use the `count_elements` method, but this can be avoided by building the graph with nested `map` uses instead. The main benefit is to allow the `MatchMatrix` to accept a wider class of inputs, which can be helpful in the definition of new matchers. A simliar relaxation is done to `get_explanation`, which also doesn't depend on it. We also add a unit test to exercise the basic construction of the graph and expose some private functions to the crate in anticipation of its use in new matchers. PiperOrigin-RevId: 707632959
1 parent 9af220e commit 4e763c4

File tree

1 file changed

+41
-25
lines changed

1 file changed

+41
-25
lines changed

googletest/src/matcher_support/match_matrix.rs

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,21 @@ pub mod internal {
9090
}
9191

9292
impl MatchMatrix {
93-
pub(crate) fn generate<
94-
'a,
95-
T: Debug + Copy + 'a,
96-
ContainerT: Debug + Copy + IntoIterator<Item = T>,
97-
>(
98-
actual: ContainerT,
93+
pub(crate) fn generate<'a, T: Debug + Copy + 'a>(
94+
actual: impl IntoIterator<Item = T>,
9995
expected: &[Box<dyn Matcher<T> + 'a>],
10096
) -> Self {
10197
let expected_len = expected.len();
102-
let mut matrix = MatchMatrix {
103-
graph: vec![vec![MatcherResult::NoMatch; expected_len]; count_elements(actual)],
104-
expected_len,
105-
};
106-
for (actual_idx, actual) in actual.into_iter().enumerate() {
107-
for (expected_idx, expected) in expected.iter().enumerate() {
108-
matrix.graph[actual_idx][expected_idx] = expected.matches(actual);
109-
}
110-
}
111-
matrix
98+
let graph = actual
99+
.into_iter()
100+
.map(|actual| {
101+
expected
102+
.iter()
103+
.map(|expected_matcher| expected_matcher.matches(actual))
104+
.collect()
105+
})
106+
.collect();
107+
MatchMatrix { graph, expected_len }
112108
}
113109

114110
pub(crate) fn is_match_for(&self, requirements: Requirements) -> bool {
@@ -430,34 +426,30 @@ pub mod internal {
430426
self.get_unmatched_expected().is_empty()
431427
}
432428

433-
fn get_matches(&self) -> impl Iterator<Item = (usize, usize)> + '_ {
429+
pub(crate) fn get_matches(&self) -> impl Iterator<Item = (usize, usize)> + '_ {
434430
self.actual_match.iter().enumerate().filter_map(|(actual_idx, maybe_expected_idx)| {
435431
maybe_expected_idx.map(|expected_idx| (actual_idx, expected_idx))
436432
})
437433
}
438434

439-
fn get_unmatched_actual(&self) -> impl Iterator<Item = usize> + '_ {
435+
pub(crate) fn get_unmatched_actual(&self) -> impl Iterator<Item = usize> + '_ {
440436
self.actual_match
441437
.iter()
442438
.enumerate()
443439
.filter(|&(_, o)| o.is_none())
444440
.map(|(actual_idx, _)| actual_idx)
445441
}
446442

447-
fn get_unmatched_expected(&self) -> Vec<usize> {
443+
pub(crate) fn get_unmatched_expected(&self) -> Vec<usize> {
448444
let matched_expected: HashSet<_> = self.actual_match.iter().flatten().collect();
449445
(0..self.expected_len)
450446
.filter(|expected_idx| !matched_expected.contains(expected_idx))
451447
.collect()
452448
}
453449

454-
pub(crate) fn get_explanation<
455-
'a,
456-
T: Debug + Copy,
457-
ContainerT: Debug + Copy + IntoIterator<Item = T>,
458-
>(
450+
pub(crate) fn get_explanation<'a, T: Debug + Copy>(
459451
&self,
460-
actual: ContainerT,
452+
actual: impl IntoIterator<Item = T>,
461453
expected: &[Box<dyn Matcher<T> + 'a>],
462454
requirements: Requirements,
463455
) -> Option<Description> {
@@ -499,4 +491,28 @@ pub mod internal {
499491
).into())
500492
}
501493
}
494+
495+
#[cfg(test)]
496+
mod tests {
497+
use super::*;
498+
use crate::prelude::*;
499+
500+
#[test]
501+
fn match_matrix_generate() {
502+
let actual = vec![1, 2, 3, 4];
503+
let expected: Vec<Box<dyn Matcher<i32>>> =
504+
vec![Box::new(eq(1)), Box::new(eq(2)), Box::new(eq(3))];
505+
let matrix = MatchMatrix::generate(actual, &expected);
506+
507+
assert_eq!(
508+
matrix.graph,
509+
vec![
510+
vec![true.into(), false.into(), false.into()],
511+
vec![false.into(), true.into(), false.into()],
512+
vec![false.into(), false.into(), true.into()],
513+
vec![false.into(), false.into(), false.into()],
514+
]
515+
);
516+
}
517+
}
502518
}

0 commit comments

Comments
 (0)