Skip to main content

swarm_engine_core/validation/
result.rs

1//! ValidationResult - 検証結果
2
3use serde::{Deserialize, Serialize};
4
5/// 検証結果
6///
7/// Validator による検証の出力。Profile に保存される。
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ValidationResult {
10    /// 合格したか
11    pub passed: bool,
12    /// ベースライン成績 (0.0-1.0)
13    pub baseline: f64,
14    /// 検証時成績 (0.0-1.0)
15    pub current: f64,
16    /// 使用した戦略名
17    pub strategy: String,
18    /// 失敗理由(失敗時のみ)
19    #[serde(default, skip_serializing_if = "Option::is_none")]
20    pub failure_reason: Option<String>,
21    /// 検証に使用したサンプル数
22    pub sample_count: usize,
23}
24
25impl ValidationResult {
26    /// 成功結果を作成
27    pub fn pass(baseline: f64, current: f64, strategy: &str, sample_count: usize) -> Self {
28        Self {
29            passed: true,
30            baseline,
31            current,
32            strategy: strategy.to_string(),
33            failure_reason: None,
34            sample_count,
35        }
36    }
37
38    /// 失敗結果を作成
39    pub fn fail(
40        baseline: f64,
41        current: f64,
42        strategy: &str,
43        reason: impl Into<String>,
44        sample_count: usize,
45    ) -> Self {
46        Self {
47            passed: false,
48            baseline,
49            current,
50            strategy: strategy.to_string(),
51            failure_reason: Some(reason.into()),
52            sample_count,
53        }
54    }
55
56    /// 改善率を計算 (%)
57    pub fn improvement(&self) -> f64 {
58        if self.baseline > 0.0 {
59            (self.current / self.baseline - 1.0) * 100.0
60        } else {
61            0.0
62        }
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_pass_result() {
72        let result = ValidationResult::pass(0.7, 0.85, "no_regression", 100);
73        assert!(result.passed);
74        assert!(result.failure_reason.is_none());
75        assert!((result.improvement() - 21.43).abs() < 0.1);
76    }
77
78    #[test]
79    fn test_fail_result() {
80        let result = ValidationResult::fail(0.7, 0.65, "no_regression", "regression detected", 100);
81        assert!(!result.passed);
82        assert!(result.failure_reason.is_some());
83    }
84
85    #[test]
86    fn test_serialization() {
87        let result = ValidationResult::pass(0.7, 0.8, "improvement", 50);
88        let json = serde_json::to_string(&result).unwrap();
89        let restored: ValidationResult = serde_json::from_str(&json).unwrap();
90        assert_eq!(restored.passed, result.passed);
91        assert_eq!(restored.strategy, result.strategy);
92    }
93}