1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#[derive(Debug)]
/// Type passed to the `on_mismatch` function, which is called when the control
/// and experimental methods create different values.
pub struct Mismatch<T> {
    /// The value generated by the control method
    pub control: T,

    /// The value generated by the experimental method
    pub experimental: T,
}

/// A `MismatchHandler` resolves differences between the control and experimental
/// values. If the two values differ, then `on_mismatch` is called. This function
/// is used to determine which value should be passed back to the aplication, and
/// possibly do some extra logging or recording if desired.
pub trait MismatchHandler<T> {
    fn on_mismatch(self, mismatch: Mismatch<T>) -> T;
}

/// A mismatch handler which always returns the value from the control function
/// and does nothing else.
pub struct AlwaysControl;

impl<T> MismatchHandler<T> for AlwaysControl {
    fn on_mismatch(self, mismatch: Mismatch<T>) -> T {
        mismatch.control
    }
}

/// FnTrait is a MismatchHandler that wraps a closure
pub struct FnTrait<F>(pub(crate) F);

impl<F, T> MismatchHandler<T> for FnTrait<F>
where
    F: FnOnce(Mismatch<T>) -> T,
{
    fn on_mismatch(self, mismatch: Mismatch<T>) -> T {
        self.0(mismatch)
    }
}