#[cfg(test)]
mod tests;
use crate::durable_io::{read_optional_regular_bytes_bounded, read_regular_bytes, write_bytes};
use canic_core::cdk::utils::hash::sha256_hex;
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
struct GeneratedLockSeedRecord {
schema_version: u8,
parent_lock_sha256: String,
manifest_sha256: String,
}
pub(super) fn refresh_seed(
directory: &Path,
parent: &Path,
manifest: &[u8],
) -> Result<(), Box<dyn std::error::Error>> {
let bytes = read_regular_bytes(parent, 16 * 1024 * 1024)?;
let expected = GeneratedLockSeedRecord {
schema_version: 1,
parent_lock_sha256: sha256_hex(&bytes),
manifest_sha256: sha256_hex(manifest),
};
let record = directory.join("lock-seed.json");
let retained = read_optional_regular_bytes_bounded(&record, 4096)
.map_err(|error| {
format!(
"cannot read generated lock seed {}: {error:?}",
record.display()
)
})?
.and_then(|bytes| serde_json::from_slice::<GeneratedLockSeedRecord>(&bytes).ok());
let lock = directory.join("Cargo.lock");
if retained.as_ref() == Some(&expected)
&& read_optional_regular_bytes_bounded(&lock, 16 * 1024 * 1024)
.map_err(|error| format!("cannot read generated lock {}: {error:?}", lock.display()))?
.is_some()
{
return Ok(());
}
write_bytes(&lock, &bytes)?;
write_bytes(&record, &serde_json::to_vec_pretty(&expected)?)?;
Ok(())
}