1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[serde(rename_all = "snake_case")]
14pub enum EvalLayer {
15 Reasoning,
17 Action,
19 Execution,
21 Safety,
23 Cost,
25}
26
27impl EvalLayer {
28 pub fn label(&self) -> &'static str {
30 match self {
31 Self::Reasoning => "reasoning",
32 Self::Action => "action",
33 Self::Execution => "execution",
34 Self::Safety => "safety",
35 Self::Cost => "cost",
36 }
37 }
38}
39
40impl std::fmt::Display for EvalLayer {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.write_str(self.label())
43 }
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
48#[serde(rename_all = "snake_case")]
49pub enum EvalTiming {
50 Inline,
52 Async,
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn eval_layer_display() {
62 assert_eq!(EvalLayer::Reasoning.to_string(), "reasoning");
63 assert_eq!(EvalLayer::Action.to_string(), "action");
64 assert_eq!(EvalLayer::Execution.to_string(), "execution");
65 assert_eq!(EvalLayer::Safety.to_string(), "safety");
66 assert_eq!(EvalLayer::Cost.to_string(), "cost");
67 }
68
69 #[test]
70 fn eval_layer_serde_roundtrip() {
71 let layer = EvalLayer::Reasoning;
72 let json = serde_json::to_string(&layer).unwrap();
73 assert_eq!(json, "\"reasoning\"");
74 let back: EvalLayer = serde_json::from_str(&json).unwrap();
75 assert_eq!(back, layer);
76 }
77
78 #[test]
79 fn eval_timing_serde_roundtrip() {
80 let timing = EvalTiming::Inline;
81 let json = serde_json::to_string(&timing).unwrap();
82 let back: EvalTiming = serde_json::from_str(&json).unwrap();
83 assert_eq!(back, timing);
84 }
85
86 #[test]
87 fn all_layers_have_labels() {
88 let layers = [
89 EvalLayer::Reasoning,
90 EvalLayer::Action,
91 EvalLayer::Execution,
92 EvalLayer::Safety,
93 EvalLayer::Cost,
94 ];
95 for layer in layers {
96 assert!(!layer.label().is_empty());
97 }
98 }
99}