rsvart 0.1.5

A small library for representing genomic variants and regions.
Documentation
use crate::genomic::{Contiged, Stranded};
use crate::ops::{contains, Located, Transposable, Unit};

pub trait Contains<C, O = Self>
where
    O: ?Sized,
{
    fn contains(&self, other: &O) -> bool;
}

impl<C, T> Contains<C> for T
where
    C: Unit,
    T: Located<C>,
{
    fn contains(&self, other: &Self) -> bool {
        contains(self.start(), self.end(), other.start(), other.end())
    }
}

pub trait GenomicallyContains<C, O = Self>
where
    O: ?Sized,
{
    fn contains(&self, other: &O) -> bool;
}

impl<C, T> GenomicallyContains<C> for T
where
    C: Unit,
    T: Located<C> + Stranded + Contiged<C>,
{
    fn contains(&self, other: &Self) -> bool {
        if self.contig().ne(other.contig()) {
            return false;
        }

        if self.strand().eq(&other.strand()) {
            return contains(self.start(), self.end(), other.start(), other.end());
        }

        let other_start = other.start_on_strand(self.strand());
        let other_end = other.end_on_strand(self.strand());
        contains(self.start(), self.end(), &other_start, &other_end)
    }
}

#[cfg(test)]
mod test {
    use super::{Contains, Located};
    use rstest::rstest;

    struct TestRegion {
        start: u8,
        end: u8,
    }

    impl Located<u8> for TestRegion {
        fn start(&self) -> &u8 {
            &self.start
        }

        fn end(&self) -> &u8 {
            &self.end
        }
    }

    #[rstest]
    #[case(TestRegion { start: 4, end: 20 }, TestRegion { start: 5, end: 16 }, true)]
    #[case(TestRegion { start: 4, end: 20 }, TestRegion { start: 20, end: 29 }, false)]
    fn test_contains(
        #[case] region_1: TestRegion,
        #[case] region_2: TestRegion,
        #[case] expected: bool,
    ) {
        assert_eq!(region_1.contains(&region_2), expected);
    }
}