use rabs_protocol::result_identity::TypedDigest;
pub const REASON_OBJECT_COLLISION_QUARANTINED: &str = "OBJECT_COLLISION_QUARANTINED";
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Admission {
Stored,
IdempotentDuplicate,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CollisionQuarantine {
pub digest: TypedDigest,
pub reason_code: &'static str,
pub existing_len: u64,
pub incoming_len: u64,
}
pub fn admit(
digest: &TypedDigest,
existing: Option<&[u8]>,
incoming: &[u8],
) -> Result<Admission, CollisionQuarantine> {
match existing {
None => Ok(Admission::Stored),
Some(held) if held == incoming => Ok(Admission::IdempotentDuplicate),
Some(held) => Err(CollisionQuarantine {
digest: digest.clone(),
reason_code: REASON_OBJECT_COLLISION_QUARANTINED,
existing_len: held.len() as u64,
incoming_len: incoming.len() as u64,
}),
}
}
#[cfg(test)]
mod tests {
use super::*;
use rabs_protocol::result_identity::DigestAlgorithm;
fn d(tag: u8) -> TypedDigest {
TypedDigest {
algorithm: DigestAlgorithm::Sha256V1,
domain: "rabs.object.v1",
bytes: [tag; 32],
}
}
#[test]
fn unknown_digest_stores_and_identical_bytes_are_idempotent() {
assert_eq!(admit(&d(1), None, b"content"), Ok(Admission::Stored));
assert_eq!(
admit(&d(1), Some(b"content"), b"content"),
Ok(Admission::IdempotentDuplicate)
);
}
#[test]
fn existing_digest_different_bytes_quarantines_never_chooses() {
let refusal = admit(&d(1), Some(b"original artifact bytes"), b"DIFFERENT bytes")
.expect_err("collision must refuse");
assert_eq!(refusal.reason_code, REASON_OBJECT_COLLISION_QUARANTINED);
assert_eq!(refusal.digest, d(1));
assert_eq!(refusal.existing_len, 23);
assert_eq!(refusal.incoming_len, 15);
match admit(&d(2), None, b"x").expect("stores") {
Admission::Stored | Admission::IdempotentDuplicate => {}
}
}
#[test]
fn empty_content_edge_cases_stay_fail_closed() {
let refusal = admit(&d(3), Some(b""), b"now nonempty").expect_err("refuses");
assert_eq!(refusal.existing_len, 0);
assert_eq!(
admit(&d(3), Some(b""), b""),
Ok(Admission::IdempotentDuplicate)
);
}
}