#![deny(missing_docs,
missing_debug_implementations, missing_copy_implementations,
trivial_casts,
unsafe_code,
unstable_features,
unused_import_braces, unused_qualifications)]
#![allow(unknown_lints)]
#[cfg(test)]
extern crate rand;
extern crate arrayvec;
mod internal;
use internal::{Aligner, prepare_time_spans};
pub use internal::{ProgressHandler, TimeDelta, TimePoint, TimeSpan};
use std::vec::from_elem;
pub fn align(
list: Vec<TimeSpan>,
reference: Vec<TimeSpan>,
split_penalty_normalized: f64,
progress_handler: Option<Box<ProgressHandler>>,
) -> Vec<TimeDelta> {
let (list_nonoverlapping, list_indices) = prepare_time_spans(list.clone());
let (ref_nonoverlapping, _) = prepare_time_spans(reference.clone());
if list_nonoverlapping.is_empty() || ref_nonoverlapping.is_empty() {
return from_elem(TimeDelta::zero(), list.len());
}
let list_len = list_nonoverlapping.len();
let aligner_opt = Aligner::new(
list_nonoverlapping,
ref_nonoverlapping,
split_penalty_normalized,
progress_handler,
);
let deltas = match aligner_opt {
Some(mut aligner) => aligner.align_all_spans(),
None => (0..list_len).map(|_| TimeDelta::zero()).collect(),
};
list_indices.into_iter().map(|i| deltas[i]).collect()
}
#[cfg(test)]
mod tests {
use super::*;
use internal::{TimePoint, prepare_time_spans};
use rand;
use rand::Rng;
fn predefined_time_spans() -> Vec<Vec<TimeSpan>> {
let t0 = TimePoint::from(0);
let t1000 = TimePoint::from(1000);
let t2000 = TimePoint::from(2000);
vec![
vec![],
vec![TimeSpan::new(t0, t0)],
vec![TimeSpan::new(t0, t1000)],
vec![TimeSpan::new(t0, t1000), TimeSpan::new(t1000, t1000)],
vec![
TimeSpan::new(t0, t1000),
TimeSpan::new(t1000, t1000),
TimeSpan::new(t1000, t2000),
],
vec![TimeSpan::new(t1000, t1000), TimeSpan::new(t1000, t1000)],
]
}
fn generate_random_time_spans() -> Vec<TimeSpan> {
let mut rng = rand::thread_rng();
let len: usize = (rng.next_u32() % 400) as usize;
let mut v = Vec::with_capacity(len);
let mut current_pos = 0i64;
for _ in 0..len {
current_pos += (rng.next_u32() % 200) as i64 - 50;
let current_len = (rng.next_u32() % 400) as i64;
v.push(TimeSpan::new(
TimePoint::from(current_pos),
TimePoint::from(current_pos + current_len),
));
}
v
}
pub fn get_test_time_spans() -> Vec<Vec<TimeSpan>> {
(0..100)
.map(|_| generate_random_time_spans())
.chain(predefined_time_spans().into_iter())
.collect()
}
pub fn get_random_prepared_test_time_spans() -> Vec<TimeSpan> {
prepare_time_spans(generate_random_time_spans()).0
}
}