use sha2::{Digest, Sha256};
pub fn book_id_from_text(text: &str) -> String {
content_sha256(text.as_bytes())
}
pub fn book_id_for_file(path: &std::path::Path) -> Option<String> {
std::fs::read(path).ok().map(|bytes| content_sha256(&bytes))
}
pub fn content_sha256(bytes: &[u8]) -> String {
let digest = Sha256::digest(bytes);
digest.iter().map(|byte| format!("{byte:02x}")).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn content_sha256_matches_known_vectors() {
assert_eq!(
content_sha256(b""),
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
);
assert_eq!(
content_sha256(b"abc"),
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
);
}
#[test]
fn book_id_is_64_hex_chars_and_deterministic() {
let id = book_id_from_text("hello world");
assert_eq!(id.len(), 64);
assert!(id.chars().all(|c| c.is_ascii_hexdigit()));
assert_eq!(id, book_id_from_text("hello world"));
}
#[test]
fn different_text_yields_different_id() {
assert_ne!(book_id_from_text("alpha"), book_id_from_text("beta"));
}
}