googletest_json_serde/matchers/
optional_matcher.rs1#[macro_export]
18macro_rules! __json_optional {
19 ($inner:expr) => {{
20 $crate::matchers::__internal_unstable_do_not_depend_on_these::JsonOptionalMatcher::new(
21 $crate::matchers::__internal_unstable_do_not_depend_on_these::IntoJsonMatcher::into_json_matcher($inner),
22 )
23 }};
24}
25
26pub mod internal {
27 use crate::matchers::json_matcher::internal::JsonMatcher;
28 use googletest::description::Description;
29 use googletest::matcher::{Matcher, MatcherBase, MatcherResult};
30 use serde_json::Value;
31
32 #[derive(MatcherBase)]
33 pub struct JsonOptionalMatcher {
34 inner: Box<dyn JsonMatcher>,
35 }
36
37 impl JsonOptionalMatcher {
38 pub fn new(inner: Box<dyn JsonMatcher>) -> Self {
39 Self { inner }
40 }
41 }
42
43 impl JsonMatcher for JsonOptionalMatcher {
44 fn allows_missing(&self) -> bool {
45 true
46 }
47 }
48
49 impl Matcher<&Value> for JsonOptionalMatcher {
50 fn matches(&self, actual: &Value) -> MatcherResult {
51 if actual.is_null() {
52 MatcherResult::Match
53 } else {
54 self.inner.matches(actual)
55 }
56 }
57
58 fn describe(&self, result: MatcherResult) -> Description {
59 match result {
60 MatcherResult::Match => "is null or matches inner matcher".into(),
61 MatcherResult::NoMatch => "neither null nor matches inner matcher".into(),
62 }
63 }
64
65 fn explain_match(&self, actual: &Value) -> Description {
66 if actual.is_null() {
67 Description::new().text("which is null")
68 } else {
69 self.inner.explain_match(actual)
70 }
71 }
72 }
73}