entrenar/citl/trainer/
trace.rs1use super::SourceSpan;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct DecisionTrace {
10 pub id: String,
12 pub decision_type: String,
14 pub description: String,
16 pub span: Option<SourceSpan>,
18 pub timestamp_ns: u64,
20 pub depends_on: Vec<String>,
22 pub metadata: HashMap<String, String>,
24}
25
26impl DecisionTrace {
27 #[must_use]
29 pub fn new(
30 id: impl Into<String>,
31 decision_type: impl Into<String>,
32 description: impl Into<String>,
33 ) -> Self {
34 Self {
35 id: id.into(),
36 decision_type: decision_type.into(),
37 description: description.into(),
38 span: None,
39 timestamp_ns: 0,
40 depends_on: Vec::new(),
41 metadata: HashMap::new(),
42 }
43 }
44
45 #[must_use]
47 pub fn with_span(mut self, span: SourceSpan) -> Self {
48 self.span = Some(span);
49 self
50 }
51
52 #[must_use]
54 pub fn with_timestamp(mut self, timestamp_ns: u64) -> Self {
55 self.timestamp_ns = timestamp_ns;
56 self
57 }
58
59 #[must_use]
61 pub fn with_dependency(mut self, dep_id: impl Into<String>) -> Self {
62 self.depends_on.push(dep_id.into());
63 self
64 }
65
66 #[must_use]
68 pub fn with_dependencies(mut self, deps: Vec<String>) -> Self {
69 self.depends_on.extend(deps);
70 self
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_decision_trace_new() {
80 let trace = DecisionTrace::new("d1", "type_inference", "Inferred type i32");
81 assert_eq!(trace.id, "d1");
82 assert_eq!(trace.decision_type, "type_inference");
83 assert_eq!(trace.description, "Inferred type i32");
84 }
85
86 #[test]
87 fn test_decision_trace_with_span() {
88 let trace =
89 DecisionTrace::new("d1", "type", "desc").with_span(SourceSpan::line("main.rs", 5));
90 assert!(trace.span.is_some());
91 }
92
93 #[test]
94 fn test_decision_trace_with_timestamp() {
95 let trace = DecisionTrace::new("d1", "type", "desc").with_timestamp(1000);
96 assert_eq!(trace.timestamp_ns, 1000);
97 }
98
99 #[test]
100 fn test_decision_trace_with_dependencies() {
101 let trace = DecisionTrace::new("d1", "type", "desc")
102 .with_dependency("d0")
103 .with_dependencies(vec!["d2".to_string(), "d3".to_string()]);
104 assert_eq!(trace.depends_on.len(), 3);
105 }
106}