Skip to main content

ic_backup/ops/persistence/
mod.rs

1//! Durable local publication and journal locking; no domain transitions.
2
3mod artifact_commit;
4mod file_lock;
5mod journal_lock;
6mod json;
7
8pub use artifact_commit::{ArtifactCommitOutcome, commit_artifact_directory};
9pub use journal_lock::{JournalLock, JournalLockError};
10pub use json::{create_json_durable, read_json, write_json_durable};
11
12use crate::{model::artifacts::ChecksumError, ops::artifacts::ArtifactError};
13use std::io;
14use thiserror::Error;
15
16/// Typed local persistence failure.
17#[derive(Debug, Error)]
18pub enum PersistenceError {
19    /// Filesystem IO failed; publication may require local reconciliation.
20    #[error(transparent)]
21    Io(#[from] io::Error),
22    /// JSON encoding or decoding failed.
23    #[error(transparent)]
24    Json(#[from] serde_json::Error),
25    /// A machine record exceeds its caller-selected byte bound.
26    #[error("record exceeds byte limit {limit}")]
27    RecordTooLarge {
28        /// Maximum accepted bytes.
29        limit: u64,
30    },
31    /// Artifact traversal or streaming failed.
32    #[error(transparent)]
33    Artifact(#[from] ArtifactError),
34    /// Verified bytes do not match the expected checksum.
35    #[error(transparent)]
36    Checksum(#[from] ChecksumError),
37    /// Publication requires distinct siblings in one directory.
38    #[error("artifact commit paths must be distinct siblings: {temporary}, {canonical}")]
39    ArtifactCommitPathMismatch {
40        /// Retained staging path.
41        temporary: String,
42        /// Canonical destination.
43        canonical: String,
44    },
45    /// Both staging and canonical trees exist; neither is overwritten.
46    #[error("artifact commit has conflicting paths: {temporary}, {canonical}")]
47    ArtifactCommitPathConflict {
48        /// Retained staging path.
49        temporary: String,
50        /// Existing canonical destination.
51        canonical: String,
52    },
53    /// Neither expected tree exists.
54    #[error("artifact commit is missing both paths: {temporary}, {canonical}")]
55    ArtifactCommitPathMissing {
56        /// Missing staging path.
57        temporary: String,
58        /// Missing canonical destination.
59        canonical: String,
60    },
61    /// Atomic no-replace directory publication is unsupported.
62    #[error("durable artifact publication is unsupported on {platform}")]
63    ArtifactCommitUnsupportedPlatform {
64        /// Host platform name.
65        platform: &'static str,
66    },
67    /// Publication found an unsafe tree entry.
68    #[error("unsupported artifact entry at {path}: {kind}")]
69    UnsupportedArtifactEntry {
70        /// Entry path.
71        path: String,
72        /// Observed entry kind.
73        kind: String,
74    },
75}