use super::*;
#[derive(Debug)]
pub(crate) struct Kept {
pub(crate) rec: Record,
pub(crate) can_hit: bool,
pub(crate) line_no: usize,
pub(crate) from_sidecar: bool,
}
#[derive(Debug, Clone, Copy)]
pub(crate) enum Row<'a> {
Rec(&'a Kept),
Spine(&'a crate::parse::SpineRow),
}
impl<'a> Row<'a> {
pub(crate) fn kept(self) -> Option<&'a Kept> {
match self {
Row::Rec(k) => Some(k),
Row::Spine(_) => None,
}
}
pub(crate) fn node(self) -> crate::model::ChainNode<'a> {
match self {
Row::Rec(k) => crate::model::ChainNode::Full(&k.rec),
Row::Spine(s) => crate::model::ChainNode::Spine(s),
}
}
pub(crate) fn line_no(self) -> usize {
match self {
Row::Rec(k) => k.line_no,
Row::Spine(s) => s.line(),
}
}
pub(crate) fn uuid(self) -> Option<&'a str> {
self.node().uuid()
}
pub(crate) fn timestamp(self) -> Option<&'a str> {
self.node().timestamp()
}
}
pub(crate) fn merge_spine(
scanned: Vec<crate::parse::SpineRow>,
demoted: Vec<crate::parse::SpineRow>,
) -> Vec<crate::parse::SpineRow> {
let mut out: Vec<crate::parse::SpineRow> = Vec::with_capacity(scanned.len() + demoted.len());
let mut a = scanned.into_iter().peekable();
let mut b = demoted.into_iter().peekable();
loop {
let take_a = match (a.peek(), b.peek()) {
(Some(x), Some(y)) => x.line() <= y.line(),
(Some(_), None) => true,
(None, Some(_)) => false,
(None, None) => break,
};
if take_a {
out.extend(a.next());
} else {
out.extend(b.next());
}
}
out
}
pub(crate) fn merge_rows<'a>(
records: &'a [Kept],
spine: &'a [crate::parse::SpineRow],
) -> Vec<Row<'a>> {
let mut out: Vec<Row<'a>> = Vec::with_capacity(records.len() + spine.len());
let (mut a, mut b) = (0usize, 0usize);
while a < records.len() && b < spine.len() {
if records[a].line_no > 0 && records[a].line_no <= spine[b].line() {
out.push(Row::Rec(&records[a]));
a += 1;
} else if records[a].line_no > 0 {
out.push(Row::Spine(&spine[b]));
b += 1;
} else {
break;
}
}
while b < spine.len() {
out.push(Row::Spine(&spine[b]));
b += 1;
}
for k in &records[a..] {
out.push(Row::Rec(k));
}
out
}