#![forbid(unsafe_code)]
use crate::core::extent::ChunkId;
use crate::format::codec::CodecError;
use crate::format::record;
use crate::store::segment::SegmentError;
pub fn verify_envelope<'a>(
segment: &'a [u8],
offset: u64,
) -> Result<Option<record::Record<'a>>, CodecError> {
record::decode(segment, offset)
}
pub fn verify_segment(
path: &std::path::Path,
limit_records: u64,
) -> Result<(u64, u64), SegmentError> {
let (records, end) = crate::store::segment::scan_segment(path, limit_records)?;
Ok((records.len() as u64, end))
}
pub fn record_content_id(segment: &[u8], offset: u64) -> Result<Option<ChunkId>, CodecError> {
Ok(verify_envelope(segment, offset)?.map(|r| r.content_id))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::format::record::{FLAG_HAS_MATERIALIZED_LEN, encode};
use crate::format::version::RecordTag;
#[test]
fn envelope_verify_detects_flip() {
let payload = b"integrity payload".to_vec();
let mut bytes = encode(
RecordTag::Data,
FLAG_HAS_MATERIALIZED_LEN,
Some(payload.len() as u64),
&payload,
);
let rec = verify_envelope(&bytes, 0).unwrap().unwrap();
assert_eq!(rec.payload, payload);
let last = bytes.len() - 1;
bytes[last] ^= 0x01;
assert!(verify_envelope(&bytes, 0).is_err());
let mut bytes2 = encode(RecordTag::Data, 0, None, &payload);
bytes2[10] ^= 0x01;
assert!(verify_envelope(&bytes2, 0).is_err());
}
}