Skip to content

Commit

Permalink
Report 4 first unique matches on error
Browse files Browse the repository at this point in the history
  • Loading branch information
trumank committed Jun 27, 2024
1 parent 8c64146 commit 62a85d1
Showing 1 changed file with 29 additions and 17 deletions.
46 changes: 29 additions & 17 deletions patternsleuth/src/resolvers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,27 +66,39 @@ pub fn resolve_rip_offset<const N: usize>(
}

/// Given an iterator of values, returns Ok(value) if all values are equal or Err
pub fn ensure_one<T: PartialEq>(data: impl IntoIterator<Item = T>) -> Result<T> {
let mut iter = data.into_iter();
let first = iter.next().context("expected at least one value")?;
for value in iter {
if value != first {
bail_out!("iter returned multiple unique values");
}
}
Ok(first)
pub fn ensure_one<T: std::fmt::Debug + PartialEq>(data: impl IntoIterator<Item = T>) -> Result<T> {
try_ensure_one(data.into_iter().map(|v| Ok(v)))
}

/// Given an iterator of values, returns Ok(value) if all values are equal or Err
pub fn try_ensure_one<T: PartialEq>(data: impl IntoIterator<Item = Result<T>>) -> Result<T> {
let mut iter = data.into_iter();
let first = iter.next().context("expected at least one value")??;
for value in iter {
if value? != first {
bail_out!("iter returned multiple unique values");
pub fn try_ensure_one<T: std::fmt::Debug + PartialEq>(
data: impl IntoIterator<Item = Result<T>>,
) -> Result<T> {
let mut reached_max = false;

// TODO use a stack vec to eliminate heap allocation
let mut unique = vec![];
for value in data.into_iter() {
let value = value?;
if !unique.contains(&value) {
unique.push(value);
}
if unique.len() >= 4 {
reached_max = true;
break;
}
}
match unique.len() {
0 => Err(ResolveError::Msg("expected at least one value".into())),
1 => Ok(unique.swap_remove(0)),
len => Err(ResolveError::Msg(
format!(
"found {}{len} unique values {unique:X?}",
if reached_max { ">=" } else { "" }
)
.into(),
)),
}
Ok(first)
}

pub type Result<T> = std::result::Result<T, ResolveError>;
Expand Down Expand Up @@ -117,7 +129,7 @@ impl From<MemoryAccessError> for ResolveError {

#[macro_export]
macro_rules! _bail_out {
($msg:literal) => {
($msg:expr) => {
return Err($crate::resolvers::ResolveError::Msg($msg.into()));
};
}
Expand Down

0 comments on commit 62a85d1

Please sign in to comment.