fn novel_section_in_order(
    lhs_novel_mps: &[&MatchedPos],
    rhs_novel_mps: &[&MatchedPos],
    lhs_prev_matched_line: Option<LineNumber>,
    rhs_prev_matched_line: Option<LineNumber>,
    opposite_to_lhs: &HashMap<LineNumber, HashSet<LineNumber>>,
    opposite_to_rhs: &HashMap<LineNumber, HashSet<LineNumber>>,
) -> Vec<(Side, MatchedPos)> {
    let mut res: Vec<(Side, MatchedPos)> = vec![];

    let mut lhs_iter = lhs_novel_mps.iter().peekable();
    let mut rhs_iter = rhs_novel_mps.iter().peekable();

    // Novel MatchedPos values that occur on the same line as the
    // previous unchanged MatchedPos must occur first.
    while let Some(lhs_mp) = lhs_iter.peek() {
        let same_line_as_prev = if let Some(lhs_prev_matched_line) = lhs_prev_matched_line {
            lhs_mp.pos.line == lhs_prev_matched_line
        } else {
            false
        };
        if same_line_as_prev {
            res.push((Side::LHS, (**lhs_mp).clone()));
            lhs_iter.next();
        } else {
            break;
        }
    }
    while let Some(rhs_mp) = rhs_iter.peek() {
        let same_line_as_prev = if let Some(rhs_prev_matched_line) = rhs_prev_matched_line {
            rhs_mp.pos.line == rhs_prev_matched_line
        } else {
            false
        };
        if same_line_as_prev {
            res.push((Side::RHS, (**rhs_mp).clone()));
            rhs_iter.next();
        } else {
            break;
        }
    }

    // Next, we want novel MatchedPos values that occur on lines
    // without any unchanged MatchedPos values.
    while let Some(lhs_mp) = lhs_iter.peek() {
        if !opposite_to_lhs.contains_key(&lhs_mp.pos.line) {
            res.push((Side::LHS, (**lhs_mp).clone()));
            lhs_iter.next();
        } else {
            break;
        }
    }
    while let Some(rhs_mp) = rhs_iter.peek() {
        if !opposite_to_rhs.contains_key(&rhs_mp.pos.line) {
            res.push((Side::RHS, (**rhs_mp).clone()));
            rhs_iter.next();
        } else {
            break;
        }
    }

    // Finally, the remainder of the novel MatchedPos values will be
    // on the same line as the following unchanged MatchedPos value.
    for lhs_mp in lhs_iter {
        res.push((Side::LHS, (*lhs_mp).clone()));
    }
    for rhs_mp in rhs_iter {
        res.push((Side::RHS, (*rhs_mp).clone()));
    }

    res
}
/// Given a sequence of novel MatchedPos values in a section between
/// two unchanged MatchedPos values, return them in an order suited
/// for displaying.
///
/// ```text
/// unchanged-before novel-1
/// novel-2
/// novel-3
/// novel-4 unchanged-after
/// ```
///
/// We need novel-1 to occur before novel-2/3, and novel-2/3 to occur
/// before novel-4, so we can safely interleave LHS and RHS whilst
/// still being monotonically increasing.
Given a sequence of novel MatchedPos values in a section between
two unchanged MatchedPos values, return them in an order suited
for displaying.



We need novel-1 to occur before novel-2/3, and novel-2/3 to occur
before novel-4, so we can safely interleave LHS and RHS whilst
still being monotonically increasing.
Given a sequence of novel MatchedPos values in a section between two unchanged MatchedPos values return them in an order suited for displaying . We need novel - 1 to occur before novel - 2 / 3 and novel - 2 / 3 to occur before novel - 4 so we can safely interleave LHS and RHS whilst still being monotonically increasing .
fn novel_section_in_order(
    lhs_novel_mps: &[&MatchedPos],
    rhs_novel_mps: &[&MatchedPos],
    lhs_prev_matched_line: Option<LineNumber>,
    rhs_prev_matched_line: Option<LineNumber>,
    opposite_to_lhs: &HashMap<LineNumber, HashSet<LineNumber>>,
    opposite_to_rhs: &HashMap<LineNumber, HashSet<LineNumber>>,
) -> Vec<(Side, MatchedPos)> {
    let mut res: Vec<(Side, MatchedPos)> = vec![];
    let mut lhs_iter = lhs_novel_mps.iter().peekable();
    let mut rhs_iter = rhs_novel_mps.iter().peekable();
    // Novel MatchedPos values that occur on the same line as the
    // previous unchanged MatchedPos must occur first.
    while let Some(lhs_mp) = lhs_iter.peek() {
        let same_line_as_prev = if let Some(lhs_prev_matched_line) = lhs_prev_matched_line {
            lhs_mp.pos.line == lhs_prev_matched_line
        } else {
            false
        };
        if same_line_as_prev {
            res.push((Side::LHS, (**lhs_mp).clone()));
            lhs_iter.next();
        } else {
            break;
        }
    }
    while let Some(rhs_mp) = rhs_iter.peek() {
        let same_line_as_prev = if let Some(rhs_prev_matched_line) = rhs_prev_matched_line {
            rhs_mp.pos.line == rhs_prev_matched_line
        } else {
            false
        };
        if same_line_as_prev {
            res.push((Side::RHS, (**rhs_mp).clone()));
            rhs_iter.next();
        } else {
            break;
        }
    }
    // Next, we want novel MatchedPos values that occur on lines
    // without any unchanged MatchedPos values.
    while let Some(lhs_mp) = lhs_iter.peek() {
        if !opposite_to_lhs.contains_key(&lhs_mp.pos.line) {
            res.push((Side::LHS, (**lhs_mp).clone()));
            lhs_iter.next();
        } else {
            break;
        }
    }
    while let Some(rhs_mp) = rhs_iter.peek() {
        if !opposite_to_rhs.contains_key(&rhs_mp.pos.line) {
            res.push((Side::RHS, (**rhs_mp).clone()));
            rhs_iter.next();
        } else {
            break;
        }
    }
    // Finally, the remainder of the novel MatchedPos values will be
    // on the same line as the following unchanged MatchedPos value.
    for lhs_mp in lhs_iter {
        res.push((Side::LHS, (*lhs_mp).clone()));
    }
    for rhs_mp in rhs_iter {
        res.push((Side::RHS, (*rhs_mp).clone()));
    }
    res
}
fn novel_section_in_order ( lhs_novel_mps : & [ & MatchedPos ] , rhs_novel_mps : & [ & MatchedPos ] , lhs_prev_matched_line : Option < LineNumber > , rhs_prev_matched_line : Option < LineNumber > , opposite_to_lhs : & HashMap < LineNumber , HashSet < LineNumber > > , opposite_to_rhs : & HashMap < LineNumber , HashSet < LineNumber > > , ) -> Vec < ( Side , MatchedPos ) > { let mut res : Vec < ( Side , MatchedPos ) > = vec ! [ ] ; let mut lhs_iter = lhs_novel_mps . iter ( ) . peekable ( ) ; let mut rhs_iter = rhs_novel_mps . iter ( ) . peekable ( ) ; // Novel MatchedPos values that occur on the same line as the // previous unchanged MatchedPos must occur first. while let Some ( lhs_mp ) = lhs_iter . peek ( ) { let same_line_as_prev = if let Some ( lhs_prev_matched_line ) = lhs_prev_matched_line { lhs_mp . pos . line == lhs_prev_matched_line } else { false } ; if same_line_as_prev { res . push ( ( Side :: LHS , ( * * lhs_mp ) . clone ( ) ) ) ; lhs_iter . next ( ) ; } else { break ; } } while let Some ( rhs_mp ) = rhs_iter . peek ( ) { let same_line_as_prev = if let Some ( rhs_prev_matched_line ) = rhs_prev_matched_line { rhs_mp . pos . line == rhs_prev_matched_line } else { false } ; if same_line_as_prev { res . push ( ( Side :: RHS , ( * * rhs_mp ) . clone ( ) ) ) ; rhs_iter . next ( ) ; } else { break ; } } // Next, we want novel MatchedPos values that occur on lines // without any unchanged MatchedPos values. while let Some ( lhs_mp ) = lhs_iter . peek ( ) { if ! opposite_to_lhs . contains_key ( & lhs_mp . pos . line ) { res . push ( ( Side :: LHS , ( * * lhs_mp ) . clone ( ) ) ) ; lhs_iter . next ( ) ; } else { break ; } } while let Some ( rhs_mp ) = rhs_iter . peek ( ) { if ! opposite_to_rhs . contains_key ( & rhs_mp . pos . line ) { res . push ( ( Side :: RHS , ( * * rhs_mp ) . clone ( ) ) ) ; rhs_iter . next ( ) ; } else { break ; } } // Finally, the remainder of the novel MatchedPos values will be // on the same line as the following unchanged MatchedPos value. for lhs_mp in lhs_iter { res . push ( ( Side :: LHS , ( * lhs_mp ) . clone ( ) ) ) ; } for rhs_mp in rhs_iter { res . push ( ( Side :: RHS , ( * rhs_mp ) . clone ( ) ) ) ; } res }
Given a sequence of novel MatchedPos values in a section between
two unchanged MatchedPos values, return them in an order suited
for displaying.
Given a sequence of novel MatchedPos values in a section between two unchanged MatchedPos values return them in an order suited for displaying .
lhs_novel_mps
&[&MatchedPos]
rhs_novel_mps
&[&MatchedPos]
lhs_prev_matched_line
Option<LineNumber>
rhs_prev_matched_line
Option<LineNumber>
opposite_to_lhs
&HashMap<LineNumber, HashSet<LineNumber>>
opposite_to_rhs
&HashMap<LineNumber, HashSet<LineNumber>>