#![cfg(test)]
use prikk_hash::to_hex;
use crate::canonical::{CanonicalEncode, CanonicalWriter};
use crate::id::{ObjectId, ObjectType};
mod hard;
mod negative;
mod snapshot;
pub(crate) struct IdCase {
pub name: &'static str,
pub object_type: ObjectType,
pub schema_version: u32,
pub payload: &'static [u8],
}
impl IdCase {
fn id(&self) -> ObjectId {
ObjectId::from_canonical_payload(self.object_type, self.schema_version, self.payload)
}
}
pub(crate) const SNAPSHOT_CASES: &[IdCase] = &[
IdCase {
name: "empty_patch",
object_type: ObjectType::Patch,
schema_version: 1,
payload: b"",
},
IdCase {
name: "patch_payload",
object_type: ObjectType::Patch,
schema_version: 1,
payload: b"payload",
},
IdCase {
name: "empty_block",
object_type: ObjectType::Block,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_refstate",
object_type: ObjectType::RefState,
schema_version: 1,
payload: b"",
},
IdCase {
name: "patch_schema2",
object_type: ObjectType::Patch,
schema_version: 2,
payload: b"payload",
},
IdCase {
name: "empty_refupdate",
object_type: ObjectType::RefUpdate,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_tag",
object_type: ObjectType::Tag,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_attestation",
object_type: ObjectType::Attestation,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_blob",
object_type: ObjectType::Blob,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_block_summary_cache",
object_type: ObjectType::BlockSummaryCache,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_recovery_note",
object_type: ObjectType::RecoveryNote,
schema_version: 1,
payload: b"",
},
IdCase {
name: "empty_project_genesis",
object_type: ObjectType::ProjectGenesis,
schema_version: 1,
payload: b"",
},
];
#[allow(clippy::expect_used)]
pub(crate) fn blob_populated_payload() -> Vec<u8> {
let blob = crate::BlobPayload::new(crate::BlobKind::Binary, vec![0xAB, 0xCD, 0xEF]);
blob.to_canonical_bytes().expect("blob encodes")
}
#[allow(clippy::expect_used)]
pub(crate) fn patch_operations_populated_payload() -> Vec<u8> {
let patch = crate::PatchPayload {
operations: vec![crate::Operation {
op_seq: 1,
op_id: None,
preconditions: Vec::new(),
kind: crate::OperationKind::CreateFile(crate::CreateFile {
path: "a.txt".to_string(),
node_id: crate::NodeId::from_bytes([0x22; 32]),
blob_id: ObjectId::from_bytes([0x11; 32]),
mode: 0o100_644,
}),
}],
parent_patch_ids: Vec::new(),
intent: None,
preconditions: Vec::new(),
};
patch.to_canonical_bytes().expect("patch encodes")
}
#[allow(clippy::expect_used)]
pub(crate) fn block_populated_payload() -> Vec<u8> {
let block = crate::BlockPayload {
parent_block_ids: vec![ObjectId::from_bytes([0x11; 32])],
kind: crate::BlockKind::Normal,
patch_ids: vec![
ObjectId::from_bytes([0x22; 32]),
ObjectId::from_bytes([0x33; 32]),
],
state_merkle_root: crate::MerkleRoot([0x44; 32]),
snapshot_blob_ref: Some(ObjectId::from_bytes([0x55; 32])),
};
block.to_canonical_bytes().expect("block encodes")
}
#[allow(clippy::expect_used)]
pub(crate) fn refs_populated_payload() -> Vec<u8> {
let refstate = crate::RefStatePayload {
ref_name: "heads/main".to_string(),
kind: crate::RefKind::Branch,
target_object_id: ObjectId::from_bytes([0x66; 32]),
update_seq: 7,
previous_ref_state_id: Some(ObjectId::from_bytes([0x77; 32])),
required_attestation_ids: vec![ObjectId::from_bytes([0x88; 32])],
};
refstate.to_canonical_bytes().expect("refstate encodes")
}
#[allow(clippy::expect_used)]
pub(crate) fn attestation_populated_payload() -> Vec<u8> {
let att = crate::AttestationPayload {
target_block_id: ObjectId::from_bytes([0x11; 32]),
policy_version: "v1".to_string(),
plugin_set_hash: vec![0x22; 32],
results: vec![crate::PluginResultEntry {
plugin_id: "audit-secrets".to_string(),
plugin_version: "0.1".to_string(),
status: crate::AttestationStatus::Pass,
report_hash: vec![0x33; 32],
finding_count: 0,
}],
status: crate::AttestationStatus::Pass,
created_at: 1_700_000_000,
is_reproducible_offline: true,
};
att.to_canonical_bytes().expect("attestation encodes")
}
#[allow(clippy::expect_used)]
pub(crate) fn codec_sample_payload() -> Vec<u8> {
let mut w = CanonicalWriter::new();
w.field_bool(1, true).expect("bool");
w.field_u16(2, 0x0102).expect("u16");
w.field_u32(3, 7).expect("u32");
w.field_string(4, "hi").expect("string");
w.field_bytes(5, &[0xAB, 0xCD]).expect("bytes");
w.finish()
}
pub(crate) fn generate_snapshot() -> String {
let mut out = String::new();
out.push_str("# prikk-object identity snapshot — generated; regenerate with PRIKK_REGEN=1\n");
out.push_str("# columns: name|object_type_code|schema_version|payload_hex|object_id_hex\n");
for case in SNAPSHOT_CASES {
out.push_str(&format!(
"{}|{}|{}|{}|{}\n",
case.name,
case.object_type.code(),
case.schema_version,
to_hex(case.payload),
case.id().to_hex(),
));
}
let codec = codec_sample_payload();
let codec_id = ObjectId::from_canonical_payload(ObjectType::Patch, 1, &codec);
out.push_str(&format!(
"codec_sample|{}|1|{}|{}\n",
ObjectType::Patch.code(),
to_hex(&codec),
codec_id.to_hex(),
));
let block_p = block_populated_payload();
let block_id = ObjectId::from_canonical_payload(ObjectType::Block, 1, &block_p);
out.push_str(&format!(
"block_populated|{}|1|{}|{}\n",
ObjectType::Block.code(),
to_hex(&block_p),
block_id.to_hex(),
));
let refs_p = refs_populated_payload();
let refs_id = ObjectId::from_canonical_payload(ObjectType::RefState, 1, &refs_p);
out.push_str(&format!(
"refs_populated|{}|1|{}|{}\n",
ObjectType::RefState.code(),
to_hex(&refs_p),
refs_id.to_hex(),
));
let att_p = attestation_populated_payload();
let att_id = ObjectId::from_canonical_payload(ObjectType::Attestation, 1, &att_p);
out.push_str(&format!(
"attestation_populated|{}|1|{}|{}\n",
ObjectType::Attestation.code(),
to_hex(&att_p),
att_id.to_hex(),
));
let blob_p = blob_populated_payload();
let blob_id = ObjectId::from_canonical_payload(ObjectType::Blob, 1, &blob_p);
out.push_str(&format!(
"blob_populated|{}|1|{}|{}\n",
ObjectType::Blob.code(),
to_hex(&blob_p),
blob_id.to_hex(),
));
out
}