ratel_ai_core/
artifact_warm.rs1use std::fmt;
6use std::str::FromStr;
7
8use crate::dense_cache::WarmError;
9use crate::embedding::EmbedderError;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum OnArtifactMiss {
14 Error,
16 Embed,
19}
20
21impl OnArtifactMiss {
22 #[must_use]
24 pub fn as_str(self) -> &'static str {
25 match self {
26 OnArtifactMiss::Error => "error",
27 OnArtifactMiss::Embed => "embed",
28 }
29 }
30}
31
32#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct ParseOnArtifactMissError(pub String);
35
36impl fmt::Display for ParseOnArtifactMissError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(
39 f,
40 "unknown on-artifact-miss policy {:?} (expected \"error\" or \"embed\")",
41 self.0
42 )
43 }
44}
45
46impl std::error::Error for ParseOnArtifactMissError {}
47
48impl FromStr for OnArtifactMiss {
49 type Err = ParseOnArtifactMissError;
50
51 fn from_str(s: &str) -> Result<Self, Self::Err> {
58 match s {
59 "error" => Ok(OnArtifactMiss::Error),
60 "embed" => Ok(OnArtifactMiss::Embed),
61 other => Err(ParseOnArtifactMissError(other.to_string())),
62 }
63 }
64}
65
66#[derive(Debug, Clone)]
69pub enum ArtifactWarmError {
70 Warm(WarmError),
72 Incomplete {
74 missing: Vec<String>,
76 },
77 Embedder(EmbedderError),
79}
80
81impl fmt::Display for ArtifactWarmError {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 match self {
84 ArtifactWarmError::Warm(e) => write!(f, "{e}"),
85 ArtifactWarmError::Incomplete { missing } => write!(
86 f,
87 "embedding artifact incomplete for the current corpus: {} id(s) missing ({})",
88 missing.len(),
89 missing.join(", ")
90 ),
91 ArtifactWarmError::Embedder(e) => write!(f, "{e}"),
92 }
93 }
94}
95
96impl std::error::Error for ArtifactWarmError {}
97
98impl From<WarmError> for ArtifactWarmError {
99 fn from(value: WarmError) -> Self {
100 Self::Warm(value)
101 }
102}
103
104impl From<EmbedderError> for ArtifactWarmError {
105 fn from(value: EmbedderError) -> Self {
106 Self::Embedder(value)
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn on_artifact_miss_round_trips_through_str() {
116 for policy in [OnArtifactMiss::Error, OnArtifactMiss::Embed] {
117 assert_eq!(policy.as_str().parse::<OnArtifactMiss>().unwrap(), policy);
118 }
119 }
120
121 #[test]
122 fn on_artifact_miss_rejects_unknown() {
123 assert!("reuse".parse::<OnArtifactMiss>().is_err());
124 }
125
126 #[test]
127 fn incomplete_display_lists_missing_ids() {
128 let incomplete = ArtifactWarmError::Incomplete {
129 missing: vec!["a".into(), "b".into()],
130 };
131 let message = incomplete.to_string();
132 assert!(message.contains("embedding artifact incomplete for the current corpus"));
133 assert!(message.contains("a, b"));
134 }
135}