use prikk_error::{PrikkError, Result};
use prikk_object::{BlobKind, BlobPayload, CanonicalEncode, NodeKind, ObjectId, ObjectType};
pub(crate) fn decode_snapshot_blob(canonical_payload: &[u8]) -> Result<Vec<u8>> {
let blob = BlobPayload::decode_canonical(canonical_payload)?;
if blob.blob_kind != BlobKind::Snapshot {
return Err(PrikkError::Integrity(
"snapshot reference points to a non-SNAPSHOT blob".to_string(),
));
}
Ok(blob.content)
}
pub(crate) fn decode_file_content_blob(canonical_payload: &[u8]) -> Result<Vec<u8>> {
let blob = BlobPayload::decode_canonical(canonical_payload)?;
if blob.blob_kind == BlobKind::Snapshot {
return Err(PrikkError::Integrity(
"file content reference points to a SNAPSHOT blob".to_string(),
));
}
Ok(blob.content)
}
pub(crate) fn decode_file_content_blob_with_kind(
canonical_payload: &[u8],
) -> Result<(prikk_object::NodeKind, Vec<u8>)> {
let blob = BlobPayload::decode_canonical(canonical_payload)?;
if blob.blob_kind == BlobKind::Snapshot {
return Err(PrikkError::Integrity(
"file content reference points to a SNAPSHOT blob".to_string(),
));
}
let kind = prikk_object::NodeKind::from_file_blob_kind(blob.blob_kind)?;
Ok((kind, blob.content))
}
#[cfg(test)]
pub(crate) fn ensure_blob_kind_is_binary(canonical_payload: &[u8]) -> Result<()> {
let blob = BlobPayload::decode_canonical(canonical_payload)?;
if blob.blob_kind == BlobKind::Binary {
return Ok(());
}
Err(PrikkError::Integrity(format!(
"ReplaceBinary requires BINARY blobs; found blob_kind {:?}",
blob.blob_kind
)))
}
pub(crate) fn ensure_blob_matches_node_kind(
bytes: &[u8],
expected: ObjectId,
old_node_kind: NodeKind,
) -> Result<()> {
let blob_kind = match old_node_kind {
NodeKind::TextFile => BlobKind::Text,
NodeKind::BinaryFile => BlobKind::Binary,
NodeKind::Symlink => {
return Err(PrikkError::Integrity(
"DeleteNode symlink node has no file-content blob".to_string(),
));
}
};
let payload = BlobPayload::new(blob_kind, bytes.to_vec());
let id = ObjectId::from_canonical_payload(ObjectType::Blob, 1, &payload.to_canonical_bytes()?);
if id == expected {
return Ok(());
}
Err(PrikkError::Integrity(format!(
"DeleteNode old_blob_id/old_node_kind mismatch: expected {expected}, got {id}"
)))
}
#[cfg(test)]
mod tests;