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