seal 0.1.6

Implementation of Needleman-Wunsch & Smith-Waterman sequence alignment.
Documentation
use crate::pair::cursor::Cursor;
use crate::pair::runs::Runs;
use crate::pair::step_mask::StepMask;
use crate::pair::steps::Steps;

#[derive(Debug)]
pub struct Alignment {
    origin: Cursor,
    steps: Vec<StepMask>,
    score: isize,
}

impl Alignment {
    pub fn new(origin: Cursor, steps: Vec<StepMask>, score: isize) -> Alignment {
        Alignment {
            origin,
            steps,
            score,
        }
    }

    pub fn origin(&self) -> &Cursor {
        &self.origin
    }

    pub fn score(&self) -> isize {
        self.score
    }

    pub fn len(&self) -> usize {
        self.steps.len()
    }

    pub fn is_empty(&self) -> bool {
        self.steps.is_empty()
    }

    pub fn steps(&self) -> Steps {
        Steps::new(self.steps.iter(), self.origin)
    }

    pub fn runs(&self) -> Runs<'_> {
        Runs::new(self.steps().peekable())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::pair::cursor::Cursor;
    use crate::pair::step_mask::StepMask;

    fn origin() -> Cursor {
        Cursor { x: 3, y: 3 }
    }

    fn steps() -> Vec<StepMask> {
        vec![StepMask::ALIGN, StepMask::ALIGN, StepMask::ALIGN]
    }

    fn score() -> isize {
        42
    }

    fn alignment() -> Alignment {
        Alignment::new(origin(), steps(), score())
    }

    #[test]
    fn origin_works() {
        assert_eq!(alignment().origin(), &origin());
    }

    #[test]
    fn steps_works() {
        for (subject, expected) in alignment().steps().zip(steps()) {
            assert_eq!(subject.mask(), expected);
        }
    }

    #[test]
    fn score_works() {
        assert_eq!(alignment().score(), score());
    }
}