forbidden_strings/runtime_cache/warning.rs
1//! Redacted cache diagnostics shared by scanner output and cli-git parsing.
2//!
3//! Every value is constructed from fixed ASCII tokens and rendered as one compact
4//! JSON line.
5//! Private token fields make an unsupported reason/recovery pairing
6//! unrepresentable without adding a constructor in this module.
7
8/// Cache condition recovered by compiling authoritative text.
9#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub(crate) enum CacheWarningReason {
11 /// Expected content-addressed artifact did not exist.
12 Missing,
13 /// Per-user cache root could not be resolved or used.
14 CacheRootUnavailable,
15 /// Existing artifact could not be read completely.
16 Unreadable,
17 /// Envelope digest disagreed with current source content.
18 SourceMismatch,
19 /// Envelope belongs to another schema,
20 /// scanner,
21 /// or platform.
22 Incompatible,
23 /// Envelope framing,
24 /// names,
25 /// or engine bytes failed validation.
26 Invalid,
27}
28
29/// One valid cache-warning record storing only fixed protocol tokens.
30#[derive(Clone, Copy, Debug, PartialEq, Eq)]
31pub struct CacheWarning {
32 /// Closed reason token.
33 reason: &'static str,
34 /// Closed recovery token paired by constructor.
35 recovery: &'static str,
36}
37
38/// Cache-warning constructors and fixed-token rendering.
39impl CacheWarning {
40 /// Read the fixed reason token without parsing its terminal JSON representation.
41 pub fn reason(&self) -> &'static str {
42 return self.reason;
43 }
44
45 /// Read the fixed recovery token paired with this warning by the existing constructors.
46 pub fn recovery(&self) -> &'static str {
47 return self.recovery;
48 }
49
50 /// Builds a warning for condition recovered by compiling authoritative text.
51 pub(crate) fn compile_from_text(reason: CacheWarningReason) -> Self {
52 return Self {
53 reason: reason_token(reason),
54 recovery: "compile-from-text",
55 }
56 }
57
58 /// Builds only warning recovered by retaining already compiled rules.
59 pub(crate) fn write_failed() -> Self {
60 return Self {
61 reason: "write-failed",
62 recovery: "continue-with-compiled-rules",
63 }
64 }
65}
66
67/// Returns fixed JSON token for one text-compilation warning reason.
68fn reason_token(reason: CacheWarningReason) -> &'static str {
69 if reason == CacheWarningReason::Missing {
70 return "missing";
71 }
72 if reason == CacheWarningReason::CacheRootUnavailable {
73 return "cache-root-unavailable";
74 }
75 if reason == CacheWarningReason::Unreadable {
76 return "unreadable";
77 }
78 if reason == CacheWarningReason::SourceMismatch {
79 return "source-mismatch";
80 }
81 if reason == CacheWarningReason::Incompatible {
82 return "incompatible";
83 }
84 return "invalid"
85}
86
87/// Renders compact single-line JSON without accepting arbitrary values.
88impl std::fmt::Display for CacheWarning {
89 /// Writes exact schema-version-1 protocol record.
90 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 return write!(
92 formatter,
93 "{{\"type\":\"forbidden-strings/cache-warning\",\"schemaVersion\":1,\"reason\":\"{}\",\"recovery\":\"{}\"}}",
94 self.reason,
95 self.recovery,
96 )
97 }
98}
99
100/// Registers closed-protocol tests.
101#[cfg(test)]
102#[path = "warning_tests.rs"]
103mod tests;