Skip to main content

entrenar/citl/trainer/
outcome.rs

1//! Compilation outcome types for CITL trainer
2
3use super::SourceSpan;
4use serde::{Deserialize, Serialize};
5
6/// Outcome of a compilation session
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum CompilationOutcome {
9    /// Compilation succeeded
10    Success,
11    /// Compilation failed with errors
12    Failure {
13        /// Error codes encountered
14        error_codes: Vec<String>,
15        /// Error spans
16        error_spans: Vec<SourceSpan>,
17        /// Error messages
18        messages: Vec<String>,
19    },
20}
21
22impl CompilationOutcome {
23    /// Create a success outcome
24    #[must_use]
25    pub fn success() -> Self {
26        Self::Success
27    }
28
29    /// Create a failure outcome
30    #[must_use]
31    pub fn failure(
32        error_codes: Vec<String>,
33        error_spans: Vec<SourceSpan>,
34        messages: Vec<String>,
35    ) -> Self {
36        Self::Failure { error_codes, error_spans, messages }
37    }
38
39    /// Check if the outcome is success
40    #[must_use]
41    pub fn is_success(&self) -> bool {
42        matches!(self, Self::Success)
43    }
44
45    /// Get error codes if failure
46    #[must_use]
47    pub fn error_codes(&self) -> Vec<&str> {
48        match self {
49            Self::Success => vec![],
50            Self::Failure { error_codes, .. } => error_codes.iter().map(String::as_str).collect(),
51        }
52    }
53
54    /// Get error spans if failure
55    #[must_use]
56    pub fn error_spans(&self) -> Vec<&SourceSpan> {
57        match self {
58            Self::Success => vec![],
59            Self::Failure { error_spans, .. } => error_spans.iter().collect(),
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_compilation_outcome_success() {
70        let outcome = CompilationOutcome::success();
71        assert!(outcome.is_success());
72        assert!(outcome.error_codes().is_empty());
73    }
74
75    #[test]
76    fn test_compilation_outcome_failure() {
77        let outcome = CompilationOutcome::failure(
78            vec!["E0308".to_string()],
79            vec![SourceSpan::line("main.rs", 5)],
80            vec!["type mismatch".to_string()],
81        );
82        assert!(!outcome.is_success());
83        assert_eq!(outcome.error_codes(), vec!["E0308"]);
84        assert_eq!(outcome.error_spans().len(), 1);
85    }
86}