Skip to main content

prikk_object/payload/
common.rs

1//! Shared payload helper types.
2
3use prikk_error::Result;
4
5use crate::{CanonicalEncode, CanonicalWriter};
6
7/// A 32-byte Merkle root for a materialized tree state.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct MerkleRoot(pub [u8; 32]);
10
11/// Advisory patch intent.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[repr(u16)]
14pub enum Intent {
15    /// Feature work.
16    Feature = 1,
17    /// Bug fix.
18    Fix = 2,
19    /// Refactoring.
20    Refactor = 3,
21    /// Documentation.
22    Docs = 4,
23    /// Test-only change.
24    Test = 5,
25}
26
27impl Intent {
28    /// Stable numeric code.
29    #[must_use]
30    pub const fn code(self) -> u16 {
31        self as u16
32    }
33}
34
35/// Operation-level condition entry.
36#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
37pub struct OperationConditionEntry {
38    /// Condition key.
39    pub key: String,
40    /// Condition value.
41    pub value: OperationCondition,
42}
43
44impl CanonicalEncode for OperationConditionEntry {
45    fn encode_canonical(&self, writer: &mut CanonicalWriter) -> Result<()> {
46        writer.field_string(1, &self.key)?;
47        writer.field_record(2, &self.value)?;
48        Ok(())
49    }
50}
51
52/// Operation precondition.
53#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
54pub enum OperationCondition {
55    /// Old content hash must match before the operation applies.
56    OldContentHash(Vec<u8>),
57    /// Named anchor must exist.
58    AnchorExists(String),
59    /// Path must exist.
60    PathExists(String),
61    /// Path must be absent.
62    PathAbsent(String),
63}
64
65impl CanonicalEncode for OperationCondition {
66    fn encode_canonical(&self, writer: &mut CanonicalWriter) -> Result<()> {
67        match self {
68            Self::OldContentHash(hash) => {
69                writer.field_u32(1, 1)?;
70                writer.field_bytes(2, hash)?;
71            }
72            Self::AnchorExists(anchor) => {
73                writer.field_u32(1, 2)?;
74                writer.field_string(2, anchor)?;
75            }
76            Self::PathExists(path) => {
77                writer.field_u32(1, 3)?;
78                writer.field_string(2, path)?;
79            }
80            Self::PathAbsent(path) => {
81                writer.field_u32(1, 4)?;
82                writer.field_string(2, path)?;
83            }
84        }
85        Ok(())
86    }
87}