use std::cmp::Ordering;
pub(crate) mod sealed {
pub trait TextWork {}
}
pub trait TextWork: sealed::TextWork {
type Error;
#[doc(hidden)]
fn comparison_work(&self, count: u64, operation: &'static str) -> Result<(), Self::Error>;
}
pub fn compare<P: TextWork>(
ctx: &P,
first: &str,
second: &str,
operation: &'static str,
) -> Result<Ordering, P::Error> {
ctx.comparison_work(1, operation)?;
compare_bytes(ctx, first, second, operation)
}
fn compare_bytes<P: TextWork>(
ctx: &P,
first: &str,
second: &str,
operation: &'static str,
) -> Result<Ordering, P::Error> {
for (first, second) in first.as_bytes().iter().zip(second.as_bytes()) {
ctx.comparison_work(1, operation)?;
let order = first.cmp(second);
if order != Ordering::Equal {
return Ok(order);
}
}
Ok(first.len().cmp(&second.len()))
}
pub fn equal<P: TextWork>(
ctx: &P,
first: &str,
second: &str,
operation: &'static str,
) -> Result<bool, P::Error> {
ctx.comparison_work(1, operation)?;
if first.len() != second.len() {
return Ok(false);
}
Ok(compare_bytes(ctx, first, second, operation)? == Ordering::Equal)
}
#[cfg(test)]
mod tests;