feat(config): add validated profile core

This commit is contained in:
Onur Özkan committed 2026-08-09 22:06:10 +03:00
1 parent 0a75860841
commit 6c5e061359
36 files changed
+3343

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
//! Persistence interface for complete validated candidate snapshots.
use core::num::NonZeroU64;
/// Storage-owned monotonically increasing committed snapshot generation.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct Generation(NonZeroU64);
impl Generation {
/// Creates a generation supplied only by a persistence backend.
pub const fn new(value: u64) -> Self {
match NonZeroU64::new(value) {
Some(value) => Self(value),
None => panic!("configuration generation must be nonzero"),
}
}
/// Parses an on-disk or wire generation, rejecting the factory sentinel.
pub const fn try_new(value: u64) -> Option<Self> {
match NonZeroU64::new(value) {
Some(value) => Some(Self(value)),
None => None,
}
}
/// Returns the committed generation value.
pub const fn get(self) -> u64 {
self.0.get()
}
}
/// Durable storage of complete configuration snapshots.
///
/// Flight implementations use a two-slot journal: a record contains a header,
/// bounded CBOR payload, integrity check, and a commit marker written last.
/// A backend must retain its previous valid record until the replacement is
/// fully verified. Host file stores may implement the same interface without
/// claiming flash power-loss semantics.
pub trait ProfileStore<C> {
/// Backend-specific I/O or integrity failure.
type Error;
/// Loads the newest valid committed candidate, if one exists.
fn load(&mut self) -> Result<Option<(Generation, C)>, Self::Error>;
/// Persists one complete already-validated candidate atomically.
fn persist(&mut self, candidate: &C) -> Result<Generation, Self::Error>;
}