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
41
42
43
use super::error::BinaryError;
use crate::{Formula, Metric};

pub struct Or<L, R> {
    left: L,
    right: R,
}

impl<L, R> Or<L, R> {
    pub fn new(left: L, right: R) -> Or<L, R> {
        Or { left, right }
    }
}

impl<T, L, R> Formula<T> for Or<L, R>
where
    L: Formula<T>,
    R: Formula<T>,
{
    type Error = BinaryError<L::Error, R::Error>;

    fn satisfied_by(&self, value: &T) -> Result<bool, Self::Error> {
        let left = self.left.satisfied_by(value).map_err(BinaryError::Left)?;
        let right = self.right.satisfied_by(value).map_err(BinaryError::Right)?;

        Ok(left || right)
    }
}

impl<T, L, R> Metric<T> for Or<L, R>
where
    L: Metric<T>,
    R: Metric<T>,
{
    type Error = BinaryError<L::Error, R::Error>;

    fn distance(&self, value: &T) -> Result<f64, Self::Error> {
        let left_dist = self.left.distance(value).map_err(BinaryError::Left)?;
        let right_dist = self.right.distance(value).map_err(BinaryError::Right)?;

        Ok(f64::max(left_dist, right_dist))
    }
}