loopsmith_core/config/
validation.rs1use super::yes;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "lowercase")]
8pub enum Mode {
9 Subjective,
10 Objective,
11 Percentage,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(tag = "type", rename_all = "snake_case")]
18pub enum Detector {
19 Script {
21 command: String,
22 #[serde(default)]
23 args: Vec<String>,
24 #[serde(default)]
25 expect_exit: Option<i32>,
26 },
27 FileExists {
29 path: String,
30 #[serde(default)]
31 non_empty: bool,
32 },
33 RegexMatch { artifact: String, pattern: String },
35 Threshold {
37 metric: String,
38 op: CompareOp,
39 value: f64,
40 },
41 Judge {
44 standard: String,
47 #[serde(default)]
48 min_score: Option<f64>,
49 },
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
53#[serde(rename_all = "lowercase")]
54pub enum CompareOp {
55 Gt,
56 Gte,
57 Lt,
58 Lte,
59 Eq,
60}
61
62impl CompareOp {
63 pub fn apply(self, lhs: f64, rhs: f64) -> bool {
64 match self {
65 CompareOp::Gt => lhs > rhs,
66 CompareOp::Gte => lhs >= rhs,
67 CompareOp::Lt => lhs < rhs,
68 CompareOp::Lte => lhs <= rhs,
69 CompareOp::Eq => (lhs - rhs).abs() < f64::EPSILON,
70 }
71 }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75#[serde(deny_unknown_fields)]
76pub struct Validation {
77 pub target: String,
79 pub name: String,
80 pub mode: Mode,
81 pub statement: String,
83 pub detector: Detector,
84 #[serde(default = "yes")]
87 pub blocking: bool,
88}