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