use crate::value::Str;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Compare<'a> {
Equal(&'a [u8]),
NotEqual(&'a [u8]),
DigestEqual(u64),
DigestNotEqual(u64),
}
impl Compare<'_> {
#[must_use]
pub fn holds(&self, current: Option<Str<'_>>) -> bool {
match *self {
Compare::Equal(want) => current.is_some_and(|v| v.eq_bytes(want)),
Compare::NotEqual(want) => !current.is_some_and(|v| v.eq_bytes(want)),
Compare::DigestEqual(want) => current.is_some_and(|v| v.digest() == want),
Compare::DigestNotEqual(want) => !current.is_some_and(|v| v.digest() == want),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const HELLO: u64 = 0x9555_e855_5c62_dcfd;
#[test]
fn equality_is_against_the_string_the_client_would_have_read() {
let int = Some(Str::Int(42));
assert!(Compare::Equal(b"42").holds(int));
assert!(!Compare::Equal(b"042").holds(int));
assert!(Compare::NotEqual(b"042").holds(int));
}
#[test]
fn a_missing_key_fails_the_equal_forms_and_passes_the_not_equal_forms() {
assert!(!Compare::Equal(b"").holds(None));
assert!(!Compare::DigestEqual(HELLO).holds(None));
assert!(Compare::NotEqual(b"anything").holds(None));
assert!(Compare::DigestNotEqual(HELLO).holds(None));
}
#[test]
fn the_digest_forms_agree_with_the_value_forms() {
let v = Some(Str::Bytes(b"hello"));
assert!(Compare::Equal(b"hello").holds(v));
assert!(Compare::DigestEqual(HELLO).holds(v));
assert!(!Compare::NotEqual(b"hello").holds(v));
assert!(!Compare::DigestNotEqual(HELLO).holds(v));
}
#[test]
fn an_int_encoded_value_digests_its_digits() {
assert_eq!(Str::Int(42).digest(), 0x1217_cb28_c0ef_2191);
assert!(Compare::DigestEqual(0x1217_cb28_c0ef_2191).holds(Some(Str::Int(42))));
}
}