Skip to main content

appcore_storage/
storage.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: storage.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/05/31 13:38:42 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/08/02 00:04:12 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Minimal storage contracts (no concrete database implementation).
12
13/// Storage-local result type.
14pub type StorageResult<T> = Result<T, StorageError>;
15
16/// Storage-local typed errors.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum StorageError {
19    /// Provider is unavailable or not open.
20    NotAvailable,
21    /// Requested repository or file does not exist.
22    RepositoryNotFound(String),
23    /// Migration execution or compatibility failed.
24    MigrationFailed(String),
25    /// Atomic storage operation failed.
26    TransactionFailed(String),
27    /// Provider does not implement transaction semantics.
28    TransactionsUnsupported,
29    /// Backup operation failed.
30    BackupFailed(String),
31    /// Path escaped or violated the provider root policy.
32    InvalidPath(String),
33    /// Cryptographic storage operation failed.
34    SecurityFailed(String),
35    /// Required authentication boundary is unavailable.
36    AuthUnavailable(String),
37}
38
39/// Coarse storage availability status.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum StorageStatus {
42    /// Provider is available for reads and writes.
43    Online,
44    /// Provider remains available with reduced guarantees.
45    Degraded,
46    /// Provider accepts reads only.
47    ReadOnly,
48    /// Provider is unavailable.
49    Offline,
50}
51
52/// Storage health snapshot.
53#[derive(Debug, Clone, PartialEq, Eq)]
54pub struct StorageHealth {
55    /// Coarse storage status.
56    pub status: StorageStatus,
57    /// Optional non-sensitive detail.
58    pub message: Option<String>,
59}
60
61/// Stable repository name.
62#[derive(Debug, Clone, PartialEq, Eq, Hash)]
63pub struct RepositoryName(
64    /// Stable repository identifier.
65    pub String,
66);
67
68/// Stable migration identifier.
69#[derive(Debug, Clone, PartialEq, Eq, Hash)]
70pub struct MigrationId(
71    /// Stable migration identifier.
72    pub String,
73);
74
75/// Backup descriptor contract.
76#[derive(Debug, Clone, PartialEq, Eq)]
77pub struct BackupDescriptor {
78    /// Provider-owned backup name.
79    pub name: String,
80    /// Creation timestamp in Unix milliseconds.
81    pub created_at_ms: u64,
82}
83
84/// Transaction contract for unit-of-work boundaries.
85pub trait Transaction {
86    /// Atomically commits the unit of work.
87    fn commit(&mut self) -> StorageResult<()>;
88    /// Discards the unit of work.
89    fn rollback(&mut self) -> StorageResult<()>;
90}
91
92/// Repository contract for app/runtime persistence boundaries.
93pub trait Repository {
94    /// Returns the stable repository name.
95    fn name(&self) -> &RepositoryName;
96}
97
98/// Migration contract.
99pub trait Migration {
100    /// Returns the stable migration identity.
101    fn id(&self) -> &MigrationId;
102    /// Applies this migration within an explicit transaction boundary.
103    fn apply(&self, tx: &mut dyn Transaction) -> StorageResult<()>;
104}
105
106/// Storage provider contract.
107pub trait StorageProvider {
108    /// Returns coarse provider availability.
109    fn status(&self) -> StorageStatus;
110    /// Returns a current provider health snapshot.
111    fn health(&self) -> StorageHealth;
112    /// Opens and validates provider resources.
113    fn open(&mut self) -> StorageResult<()>;
114    /// Closes provider resources.
115    fn close(&mut self) -> StorageResult<()>;
116    /// Begins a real unit of work or fails explicitly when unsupported.
117    fn begin_transaction(&mut self) -> StorageResult<Box<dyn Transaction>>;
118    /// Lists provider-owned backups.
119    fn list_backups(&self) -> Vec<BackupDescriptor>;
120}
121
122#[path = "storage_auth_remote.rs"]
123mod storage_auth_remote;
124#[path = "storage_backup.rs"]
125mod storage_backup;
126#[path = "storage_backup_list.rs"]
127mod storage_backup_list;
128#[path = "storage_file.rs"]
129mod storage_file;
130#[path = "storage_file_fs.rs"]
131mod storage_file_fs;
132#[path = "storage_tree.rs"]
133mod storage_tree;
134pub use storage_auth_remote::{
135    data_claims, make_auth_request, now_ms, open_remote_request, open_remote_response,
136    process_remote_request, seal_remote_request, seal_remote_response, transport_claims,
137    validate_auth_resource, AuthRemoteRequest, AuthRemoteResponse, RemoteAuthStorageClient,
138    AUTH_REMOTE_ENDPOINT, AUTH_REMOTE_SCHEMA, DEFAULT_AUTH_REMOTE_MAX_BYTES,
139    DEFAULT_AUTH_REMOTE_TIMEOUT_MS, DEFAULT_AUTH_REMOTE_TTL_MS,
140};
141pub use storage_backup::{
142    StorageBackupManifestFileV1, StorageBackupManifestV1, STORAGE_BACKUP_FORMAT_V1,
143};
144#[path = "storage_dnt.rs"]
145mod storage_dnt;
146pub use storage_dnt::{
147    DntFileObjectStore, DntFileSecretStore, DntFileSnapshotStore, SealedObjectStore,
148    SealedSecretStore, SealedSnapshotStore, SealedStoragePolicy,
149};
150pub use storage_file::FileStorageProvider;
151#[cfg(test)]
152pub(crate) use storage_file_fs::tmp_path_for;
153
154#[cfg(test)]
155#[path = "storage_backup_tests.rs"]
156mod storage_backup_tests;
157#[cfg(test)]
158#[path = "storage_tests.rs"]
159mod storage_tests;