icydb_core/sanitize.rs
1//! Module: sanitize
2//!
3//! Responsibility: top-level sanitize entrypoint over visitable trees.
4//! Does not own: visitor diagnostics or per-type sanitize implementations.
5//! Boundary: convenient crate-level sanitize surface that delegates to visitor traversal.
6
7use crate::{
8 traits::Visitable,
9 types::Timestamp,
10 visitor::{
11 PathSegment, VisitorError, VisitorMutAdapter, perform_visit_mut, sanitize::SanitizeVisitor,
12 },
13};
14
15///
16/// SanitizeWriteMode
17///
18/// Explicit write-mode contract exposed to sanitizer-driven write preflight.
19///
20#[derive(Clone, Copy, Debug, Eq, PartialEq)]
21pub enum SanitizeWriteMode {
22 Insert,
23 Replace,
24 Update,
25}
26
27///
28/// SanitizeWriteContext
29///
30/// Shared write preflight context passed through sanitizer traversal.
31/// This keeps lifecycle-managed fields on one deterministic mutation contract.
32///
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub struct SanitizeWriteContext {
35 mode: SanitizeWriteMode,
36 now: Timestamp,
37}
38
39impl SanitizeWriteContext {
40 /// Build one explicit write preflight context.
41 #[must_use]
42 pub const fn new(mode: SanitizeWriteMode, now: Timestamp) -> Self {
43 Self { mode, now }
44 }
45
46 /// Return the write-mode contract active for this preflight pass.
47 #[must_use]
48 pub const fn mode(self) -> SanitizeWriteMode {
49 self.mode
50 }
51
52 /// Return the stable timestamp captured for this preflight pass.
53 #[must_use]
54 pub const fn now(self) -> Timestamp {
55 self.now
56 }
57}
58
59///
60/// sanitize
61///
62/// Run the sanitizer visitor over a mutable visitable tree.
63///
64/// Sanitization is total and non-failing. Any issues discovered during
65/// sanitization are reported via the returned `VisitorError`.
66///
67pub fn sanitize(node: &mut dyn Visitable) -> Result<(), VisitorError> {
68 sanitize_with_context(node, None)
69}
70
71///
72/// sanitize_with_context
73///
74/// Run the sanitizer visitor over a mutable visitable tree with one explicit
75/// optional write context.
76///
77/// Sanitization is total and non-failing. Any issues discovered during
78/// sanitization are reported via the returned `VisitorError`.
79///
80pub fn sanitize_with_context(
81 node: &mut dyn Visitable,
82 write_context: Option<SanitizeWriteContext>,
83) -> Result<(), VisitorError> {
84 let visitor = SanitizeVisitor::new();
85 let mut adapter = VisitorMutAdapter::with_sanitize_write_context(visitor, write_context);
86
87 perform_visit_mut(&mut adapter, node, PathSegment::Empty);
88
89 adapter.result().map_err(VisitorError::from)
90}