use debugid::{CodeId, DebugId};
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) -> Option<CodeId>;
fn debug_file(&self) -> Option<Cow<'_, str>>;
fn debug_identifier(&self) -> Option<DebugId>;
fn version(&self) -> Option<Cow<'_, str>>;
}
impl Module for (&str, DebugId) {
fn base_address(&self) -> u64 {
0
}
fn size(&self) -> u64 {
0
}
fn code_file(&self) -> Cow<'_, str> {
Cow::Borrowed("")
}
fn code_identifier(&self) -> Option<CodeId> {
None
}
fn debug_file(&self) -> Option<Cow<'_, str>> {
let &(file, _id) = self;
Some(Cow::Borrowed(file))
}
fn debug_identifier(&self) -> Option<DebugId> {
let &(_file, id) = self;
Some(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::try_from_iter(vec).unwrap()
}
}
impl<I, V> IntoRangeMapSafe<V> for I
where
I: IntoIterator<Item = (Option<Range<u64>>, V)> + Sized,
V: Clone + Debug + Eq,
{
}