use googletest::description::Description; use googletest::matcher::MatcherResult; use googletest::prelude::*; use protobuf::{AbsentField, Optional, PresentField, ProxiedWithPresence}; use std::marker::PhantomData; /// =============================== /// IS_UNSET /// =============================== pub fn is_unset<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized + 'a>() -> impl Matcher, AbsentField<'a, T>>> { UnsetMatcher:: { _phantom: PhantomData } } struct UnsetMatcher<'a, T: ProxiedWithPresence + ?Sized> { _phantom: PhantomData>, } impl<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized> Matcher for UnsetMatcher<'a, T> { type ActualT = Optional, AbsentField<'a, T>>; fn matches(&self, actual: &Self::ActualT) -> MatcherResult { actual.is_unset().into() } fn describe(&self, matcher_result: MatcherResult) -> Description { match matcher_result { MatcherResult::Match => "is not set".into(), MatcherResult::NoMatch => "is set".into(), } } } /// =============================== /// IS_SET /// =============================== pub fn is_set<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized + 'a>() -> impl Matcher, AbsentField<'a, T>>> { SetMatcher:: { _phantom: PhantomData } } struct SetMatcher<'a, T: ProxiedWithPresence + ?Sized> { _phantom: PhantomData>, } impl<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized> Matcher for SetMatcher<'a, T> { type ActualT = Optional, AbsentField<'a, T>>; fn matches(&self, actual: &Self::ActualT) -> MatcherResult { actual.is_set().into() } fn describe(&self, matcher_result: MatcherResult) -> Description { match matcher_result { MatcherResult::Match => "is set".into(), MatcherResult::NoMatch => "is not set".into(), } } }