///|
pub struct QualityPolicy {
name : String
lower_limit : Double
upper_limit : Double
warning_margin : Double
critical_margin : Double
required_samples : Int
enabled : Bool
} derive(Debug, ToJson)
///|
pub struct PolicyDecision {
accepted : Bool
warning : Bool
critical : Bool
reason : String
score : Double
} derive(Debug, ToJson)
///|
pub fn quality_policy(
name~ : String,
lower_limit~ : Double,
upper_limit~ : Double,
warning_margin~ : Double,
critical_margin~ : Double,
required_samples~ : Int,
) -> QualityPolicy {
{
name,
lower_limit,
upper_limit,
warning_margin: warning_margin.max(0.0),
critical_margin: critical_margin.max(0.0),
required_samples: required_samples.max(1),
enabled: true,
}
}
///|
pub fn disable_policy(policy : QualityPolicy) -> QualityPolicy {
{ ..policy, enabled: false }
}
///|
pub fn policy_distance(policy : QualityPolicy, value : Double) -> Double {
if value < policy.lower_limit {
policy.lower_limit - value
} else if value > policy.upper_limit {
value - policy.upper_limit
} else {
0.0
}
}
///|
pub fn evaluate_policy(
policy : QualityPolicy,
values : Array[Double],
) -> PolicyDecision {
if !policy.enabled {
return {
accepted: true,
warning: false,
critical: false,
reason: "disabled",
score: 0.0,
}
}
if values.length() < policy.required_samples {
return {
accepted: false,
warning: false,
critical: true,
reason: "insufficient_samples",
score: 0.0,
}
}
let mut worst = 0.0
for value in values {
worst = worst.max(policy_distance(policy, value))
}
let critical = worst > policy.critical_margin
let warning = worst > policy.warning_margin
{
accepted: !critical,
warning,
critical,
reason: if critical {
"critical_out_of_spec"
} else if warning {
"warning_margin"
} else {
"within_policy"
},
score: worst,
}
}
///|
pub fn policy_defect_count(
policy : QualityPolicy,
values : Array[Double],
) -> Int {
let mut count = 0
for value in values {
if policy_distance(policy, value) > 0.0 {
count += 1
}
}
count
}
///|
pub fn policy_defect_rate(
policy : QualityPolicy,
values : Array[Double],
) -> Double {
if values.length() == 0 {
0.0
} else {
policy_defect_count(policy, values).to_double() /
values.length().to_double()
}
}
///|
pub fn policy_yield(policy : QualityPolicy, values : Array[Double]) -> Double {
1.0 - policy_defect_rate(policy, values)
}
///|
pub fn policy_margin_ok(policy : QualityPolicy, value : Double) -> Bool {
policy_distance(policy, value) <= policy.warning_margin
}
///|
pub fn policy_summary(policies : Array[QualityPolicy]) -> Array[String] {
let result : Array[String] = []
for policy in policies {
result.push(policy.name)
}
result
}
///|
pub fn policies_enabled(policies : Array[QualityPolicy]) -> Int {
let mut count = 0
for policy in policies {
if policy.enabled {
count += 1
}
}
count
}
///|
pub fn most_restrictive_policy(
policies : Array[QualityPolicy],
) -> QualityPolicy? {
if policies.length() == 0 {
None
} else {
let mut result = policies[0]
for policy in policies[1:] {
if policy.warning_margin < result.warning_margin {
result = policy
}
}
Some(result)
}
}