entrenar/citl/pattern_store/
fix_pattern.rs1use super::ChunkId;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct FixPattern {
10 pub id: ChunkId,
12 pub error_code: String,
14 pub decision_sequence: Vec<String>,
16 pub fix_diff: String,
18 pub success_count: u32,
20 pub attempt_count: u32,
22 pub metadata: HashMap<String, String>,
24}
25
26impl FixPattern {
27 #[must_use]
29 pub fn new(error_code: impl Into<String>, fix_diff: impl Into<String>) -> Self {
30 Self {
31 id: ChunkId::new(),
32 error_code: error_code.into(),
33 decision_sequence: Vec::new(),
34 fix_diff: fix_diff.into(),
35 success_count: 0,
36 attempt_count: 0,
37 metadata: HashMap::new(),
38 }
39 }
40
41 #[must_use]
43 pub fn with_decision(mut self, decision: impl Into<String>) -> Self {
44 self.decision_sequence.push(decision.into());
45 self
46 }
47
48 #[must_use]
50 pub fn with_decisions(mut self, decisions: Vec<String>) -> Self {
51 self.decision_sequence.extend(decisions);
52 self
53 }
54
55 pub fn record_success(&mut self) {
57 self.success_count += 1;
58 self.attempt_count += 1;
59 }
60
61 pub fn record_failure(&mut self) {
63 self.attempt_count += 1;
64 }
65
66 #[must_use]
68 pub fn success_rate(&self) -> f32 {
69 if self.attempt_count == 0 {
70 0.0
71 } else {
72 self.success_count as f32 / self.attempt_count as f32
73 }
74 }
75
76 #[must_use]
78 pub fn to_searchable_text(&self) -> String {
79 let decisions = self.decision_sequence.join(" ");
80 format!("{} {} {}", self.error_code, decisions, self.fix_diff)
81 }
82}