const PREFIX: &str = "<!-- Installed by provenance ";
const HASH_PREFIX: &str = "; content hash fnv1a64:";
const SUFFIX: &str = " -->";
const HASH_LENGTH: usize = 16;
pub fn header(content: &str) -> String {
format!(
"{PREFIX}{}{HASH_PREFIX}{}{SUFFIX}",
env!("CARGO_PKG_VERSION"),
fnv1a64(content)
)
}
pub fn header_hash(header: &str) -> Option<&str> {
let header = header.strip_prefix(PREFIX)?;
let (version, hash) = header.split_once(HASH_PREFIX)?;
let hash = hash.strip_suffix(SUFFIX)?;
(!version.is_empty()
&& hash.len() == HASH_LENGTH
&& hash.bytes().all(|byte| byte.is_ascii_hexdigit()))
.then_some(hash)
}
pub fn fnv1a64(content: &str) -> String {
let mut hash = 0xcbf2_9ce4_8422_2325_u64;
for byte in content.as_bytes() {
hash ^= u64::from(*byte);
hash = hash.wrapping_mul(0x0000_0100_0000_01b3);
}
format!("{hash:016x}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_reader_takes_back_apart_what_the_writer_wrote() {
for content in ["", "---\nname: old\n---\npayload\n", "é 日本語\r\n"] {
let stamp = header(content);
assert_eq!(header_hash(&stamp), Some(fnv1a64(content).as_str()));
}
}
#[test]
fn the_stamp_keeps_its_published_shape() {
assert_eq!(
header("payload\n"),
format!(
"<!-- Installed by provenance {}; content hash fnv1a64:acb27c196e1c811d -->",
env!("CARGO_PKG_VERSION")
)
);
}
}