xpct/core/
adapter.rs

1use std::marker::PhantomData;
2
3use super::{
4    DynTransformMatch, FormattedFailure, Match, MatchFailure, MatchOutcome, MatcherFormat,
5    TransformMatch,
6};
7
8#[derive(Debug)]
9pub(super) struct DynTransformMatchAdapter<M, Fmt: MatcherFormat> {
10    matcher: M,
11    format: Fmt,
12}
13
14impl<M, Fmt: MatcherFormat> DynTransformMatchAdapter<M, Fmt> {
15    pub fn new(matcher: M, format: Fmt) -> Self {
16        Self { matcher, format }
17    }
18}
19
20impl<M, Fmt> DynTransformMatch for DynTransformMatchAdapter<M, Fmt>
21where
22    M: TransformMatch,
23    Fmt: MatcherFormat<Pos = M::PosFail, Neg = M::NegFail>,
24{
25    type In = M::In;
26
27    type PosOut = M::PosOut;
28    type NegOut = M::NegOut;
29
30    fn match_pos(
31        self: Box<Self>,
32        actual: Self::In,
33    ) -> crate::Result<MatchOutcome<Self::PosOut, FormattedFailure>> {
34        match self.matcher.match_pos(actual) {
35            Ok(MatchOutcome::Success(out)) => Ok(MatchOutcome::Success(out)),
36            Ok(MatchOutcome::Fail(result)) => Ok(MatchOutcome::Fail(FormattedFailure::new(
37                MatchFailure::Pos(result),
38                self.format,
39            )?)),
40            Err(error) => Err(error),
41        }
42    }
43
44    fn match_neg(
45        self: Box<Self>,
46        actual: Self::In,
47    ) -> crate::Result<MatchOutcome<Self::NegOut, FormattedFailure>> {
48        match self.matcher.match_neg(actual) {
49            Ok(MatchOutcome::Success(out)) => Ok(MatchOutcome::Success(out)),
50            Ok(MatchOutcome::Fail(result)) => Ok(MatchOutcome::Fail(FormattedFailure::new(
51                MatchFailure::Neg(result),
52                self.format,
53            )?)),
54            Err(error) => Err(error),
55        }
56    }
57}
58
59#[derive(Debug)]
60pub(super) struct MatchAdapter<M, Actual>
61where
62    M: Match<Actual>,
63{
64    inner: M,
65    marker: PhantomData<Actual>,
66}
67
68impl<M, Actual> MatchAdapter<M, Actual>
69where
70    M: Match<Actual>,
71{
72    pub fn new(inner: M) -> Self {
73        Self {
74            inner,
75            marker: PhantomData,
76        }
77    }
78}
79
80impl<M, Actual> TransformMatch for MatchAdapter<M, Actual>
81where
82    M: Match<Actual>,
83{
84    type In = Actual;
85
86    type PosOut = Actual;
87    type NegOut = Actual;
88
89    type PosFail = M::Fail;
90    type NegFail = M::Fail;
91
92    fn match_pos(
93        mut self,
94        actual: Self::In,
95    ) -> crate::Result<MatchOutcome<Self::PosOut, Self::PosFail>> {
96        match self.inner.matches(&actual) {
97            Ok(true) => Ok(MatchOutcome::Success(actual)),
98            Ok(false) => Ok(MatchOutcome::Fail(self.inner.fail(actual))),
99            Err(error) => Err(error),
100        }
101    }
102
103    fn match_neg(
104        mut self,
105        actual: Self::In,
106    ) -> crate::Result<MatchOutcome<Self::NegOut, Self::NegFail>> {
107        match self.inner.matches(&actual) {
108            Ok(true) => Ok(MatchOutcome::Fail(self.inner.fail(actual))),
109            Ok(false) => Ok(MatchOutcome::Success(actual)),
110            Err(error) => Err(error),
111        }
112    }
113}
114
115#[derive(Debug)]
116pub(super) struct NegTransformMatchAdapter<M> {
117    matcher: M,
118}
119
120impl<M> NegTransformMatchAdapter<M> {
121    pub fn new(matcher: M) -> Self {
122        Self { matcher }
123    }
124}
125
126impl<M> TransformMatch for NegTransformMatchAdapter<M>
127where
128    M: TransformMatch,
129{
130    type In = M::In;
131
132    type PosOut = M::NegOut;
133    type NegOut = M::PosOut;
134
135    type PosFail = M::NegFail;
136    type NegFail = M::PosFail;
137
138    fn match_pos(
139        self,
140        actual: Self::In,
141    ) -> crate::Result<MatchOutcome<Self::PosOut, Self::PosFail>> {
142        self.matcher.match_neg(actual)
143    }
144
145    fn match_neg(
146        self,
147        actual: Self::In,
148    ) -> crate::Result<MatchOutcome<Self::NegOut, Self::NegFail>> {
149        self.matcher.match_pos(actual)
150    }
151}