googletest_json_serde/matchers/
each_matcher.rs1#[macro_export]
24#[doc(hidden)]
25macro_rules! __json_each {
26 ($inner:expr) => {
27 $crate::matchers::__internal_unstable_do_not_depend_on_these::JsonEachMatcher::new(
28 $crate::matchers::__internal_unstable_do_not_depend_on_these::IntoJsonMatcher::into_json_matcher($inner)
29 )
30 };
31}
32
33pub mod internal {
34 use crate::matchers::__internal_unstable_do_not_depend_on_these::JsonMatcher;
35 use googletest::description::Description;
36 use googletest::matcher::{Matcher, MatcherBase, MatcherResult};
37 use serde_json::Value;
38
39 #[derive(MatcherBase)]
40 pub struct JsonEachMatcher {
41 inner: Box<dyn JsonMatcher>,
42 }
43
44 impl JsonEachMatcher {
45 pub fn new(inner: Box<dyn JsonMatcher>) -> Self {
46 Self { inner }
47 }
48 }
49
50 impl JsonMatcher for JsonEachMatcher {}
51 impl Matcher<&Value> for JsonEachMatcher {
52 fn matches(&self, actual: &Value) -> MatcherResult {
53 let arr = match actual {
54 Value::Array(a) => a,
55 _ => return MatcherResult::NoMatch,
56 };
57 for v in arr {
58 if self.inner.matches(v) == MatcherResult::NoMatch {
59 return MatcherResult::NoMatch;
60 }
61 }
62 MatcherResult::Match
63 }
64
65 fn describe(&self, result: MatcherResult) -> Description {
66 match result {
67 MatcherResult::Match => format!(
68 "JSON array where each element {}",
69 self.inner.describe(MatcherResult::Match)
70 )
71 .into(),
72 MatcherResult::NoMatch => format!(
73 "JSON array where each element {}",
74 self.inner.describe(MatcherResult::NoMatch)
75 )
76 .into(),
77 }
78 }
79
80 fn explain_match(&self, actual: &Value) -> Description {
81 let arr = match actual {
82 Value::Array(a) => a,
83 _ => return Description::new().text("which is not a JSON array"),
84 };
85 for (i, v) in arr.iter().enumerate() {
86 if self.inner.matches(v) == MatcherResult::NoMatch {
87 return format!(
88 "element #{} ({}) did not match: {}",
89 i,
90 v,
91 self.inner.explain_match(v)
92 )
93 .into();
94 }
95 }
96 format!(
97 "all {} elements matched: {}",
98 arr.len(),
99 self.inner.describe(MatcherResult::Match)
100 )
101 .into()
102 }
103 }
104}