use sha2::{Digest, Sha256};
const HEX: &[u8; 16] = b"0123456789abcdef";
#[doc(hidden)]
#[must_use]
pub fn generated_schema_submission_key(
fragment: &[u8],
plan: Option<&[u8]>,
attempt: u64,
assignments: &[(&str, &str, Option<&str>)],
) -> String {
let mut hasher = Sha256::new();
hasher.update(b"icydb.generated-schema-submission.attempt.v1");
hasher.update((fragment.len() as u64).to_be_bytes());
hasher.update(fragment);
let plan = plan.unwrap_or_default();
hasher.update((plan.len() as u64).to_be_bytes());
hasher.update(plan);
hasher.update(attempt.to_be_bytes());
let mut assignments = assignments.to_vec();
assignments.sort_unstable();
hasher.update((assignments.len() as u64).to_be_bytes());
for (entity, store, journal_key) in assignments {
for value in [entity, store] {
hasher.update((value.len() as u64).to_be_bytes());
hasher.update(value.as_bytes());
}
hasher.update([u8::from(journal_key.is_some())]);
if let Some(key) = journal_key {
hasher.update((key.len() as u64).to_be_bytes());
hasher.update(key.as_bytes());
}
}
let digest = hasher.finalize();
let mut key = String::with_capacity(74);
key.push_str("generated/");
for byte in digest {
key.push(char::from(HEX[usize::from(byte >> 4)]));
key.push(char::from(HEX[usize::from(byte & 15)]));
}
key
}
#[cfg(test)]
mod tests;