use range_map::{Range, RangeMap};
use std::borrow::Cow;
use std::cmp;
use std::fmt::Debug;
pub trait Module {
fn base_address(&self) -> u64;
fn size(&self) -> u64;
fn code_file(&self) -> Cow<str>;
fn code_identifier(&self) -> Cow<str>;
fn debug_file(&self) -> Option<Cow<str>>;
fn debug_identifier(&self) -> Option<Cow<str>>;
fn version(&self) -> Option<Cow<str>>;
}
impl<'a> Module for (&'a str, &'a str) {
fn base_address(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
fn code_file(&self) -> Cow<str> {
Cow::Borrowed("")
}
fn code_identifier(&self) -> Cow<str> {
Cow::Borrowed("")
}
fn debug_file(&self) -> Option<Cow<str>> {
let &(file, _id) = self;
Some(Cow::Borrowed(file))
}
fn debug_identifier(&self) -> Option<Cow<str>> {
let &(_file, id) = self;
Some(Cow::Borrowed(id))
}
fn version(&self) -> Option<Cow<str>> {
None
}
}
pub trait IntoRangeMapSafe<V>: IntoIterator<Item = (Option<Range<u64>>, V)> + Sized
where
V: Clone + Debug + Eq,
{
fn into_rangemap_safe(self) -> RangeMap<u64, V> {
let mut input: Vec<_> = self.into_iter().collect();
input.sort_by_key(|x| x.0);
let mut vec: Vec<(Range<u64>, V)> = Vec::with_capacity(input.len());
for (range, val) in input.into_iter() {
if range.is_none() {
continue;
}
let range = range.unwrap();
if let Some(&mut (ref mut last_range, ref last_val)) = vec.last_mut() {
if range.start <= last_range.end && &val != last_val {
continue;
}
if range.start <= last_range.end.saturating_add(1) && &val == last_val {
last_range.end = cmp::max(range.end, last_range.end);
continue;
}
}
vec.push((range, val));
}
RangeMap::from_sorted_vec(vec)
}
}
impl<I, V> IntoRangeMapSafe<V> for I
where
I: IntoIterator<Item = (Option<Range<u64>>, V)> + Sized,
V: Clone + Debug + Eq,
{
}