mod bin;
mod flow;
mod flow_id;
mod limit;
mod model;
mod pattern;
mod sub_test;
mod template_loader;
mod test;
mod variable;
pub use super::ResourcesType;
use crate::Result as OrigenResult;
pub use bin::Bin;
pub use flow::Flow;
pub use flow_id::FlowID;
pub use limit::{Limit, LimitType};
pub use model::Model;
pub use pattern::Pattern;
pub use pattern::PatternReferenceType;
pub use pattern::PatternType;
use std::fmt;
use std::str::FromStr;
pub use sub_test::SubTest;
pub use template_loader::{
load_test_from_lib, TestTemplate, TestTemplateCollection, TestTemplateParameter,
};
pub use test::{Test, TestCollection, TestCollectionItem};
pub use variable::Variable;
pub use variable::VariableOperation;
pub use variable::VariableType;
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum PatternGroupType {
Patset,
Patgroup,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum GroupType {
Flow,
Test,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum BinType {
Good,
Bad,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum LimitSelector {
Lo,
Hi,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum FlowCondition {
IfJob(Vec<String>),
UnlessJob(Vec<String>),
IfEnable(Vec<String>),
UnlessEnable(Vec<String>),
IfPassed(Vec<FlowID>),
IfAnyPassed(Vec<FlowID>),
IfAllPassed(Vec<FlowID>),
IfAnySitesPassed(Vec<FlowID>),
IfAllSitesPassed(Vec<FlowID>),
IfFailed(Vec<FlowID>),
IfAnyFailed(Vec<FlowID>),
IfAllFailed(Vec<FlowID>),
IfAnySitesFailed(Vec<FlowID>),
IfAllSitesFailed(Vec<FlowID>),
IfRan(Vec<FlowID>),
UnlessRan(Vec<FlowID>),
IfFlag(Vec<String>),
UnlessFlag(Vec<String>),
IfAnySitesFlag(Vec<String>),
IfAllSitesFlag(Vec<String>),
IfExpr(String),
UnlessExpr(String),
IfVar(String, String, String),
UnlessVar(String, String, String),
IfSite(Vec<usize>),
UnlessSite(Vec<usize>),
IfBin(usize, BinType),
UnlessBin(usize, BinType),
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub enum ParamValue {
String(String),
Int(i64),
UInt(u64),
Float(f64),
Current(f64),
Voltage(f64),
Time(f64),
Frequency(f64),
Bool(bool),
Any(String),
}
impl ParamValue {
pub fn is_type(&self, kind: &ParamType) -> bool {
match self {
ParamValue::String(_) => kind == &ParamType::String,
ParamValue::Int(_) => kind == &ParamType::Int,
ParamValue::UInt(_) => kind == &ParamType::UInt,
ParamValue::Float(_) => kind == &ParamType::Float,
ParamValue::Current(_) => kind == &ParamType::Current,
ParamValue::Voltage(_) => kind == &ParamType::Voltage,
ParamValue::Time(_) => kind == &ParamType::Time,
ParamValue::Frequency(_) => kind == &ParamType::Frequency,
ParamValue::Bool(_) => kind == &ParamType::Bool,
ParamValue::Any(_) => true,
}
}
pub fn to_bool(&self) -> OrigenResult<bool> {
if let ParamValue::Bool(v) = self {
Ok(*v)
} else {
bail!("Not a boolean value")
}
}
}
impl fmt::Display for ParamValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ParamValue::String(v) => write!(f, "{}", v),
ParamValue::Int(v) => write!(f, "{}", v),
ParamValue::UInt(v) => write!(f, "{}", v),
ParamValue::Float(v) => write!(f, "{}", v),
ParamValue::Current(v) => write!(f, "{}", v),
ParamValue::Voltage(v) => write!(f, "{}", v),
ParamValue::Time(v) => write!(f, "{}", v),
ParamValue::Frequency(v) => write!(f, "{}", v),
ParamValue::Bool(v) => write!(f, "{}", v),
ParamValue::Any(v) => write!(f, "{}", v),
}
}
}
#[derive(Debug, PartialEq, Clone, Serialize, Display)]
pub enum ParamType {
String,
Int,
UInt,
Float,
Current,
Voltage,
Time,
Frequency,
Bool,
Any,
}
impl FromStr for ParamType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let normalized = s.trim().to_ascii_lowercase().replace('_', "");
match normalized.as_str() {
"string" | "class" => Ok(ParamType::String),
"pinstring" | "specvalue" | "specvariable" | "contextpins" | "optionlist" => {
Ok(ParamType::String)
}
"int" | "integer" => Ok(ParamType::Int),
"long" => Ok(ParamType::Int),
"uint" | "uinteger" => Ok(ParamType::UInt),
"float" | "double" | "number" | "num" => Ok(ParamType::Float),
"current" | "curr" | "i" => Ok(ParamType::Current),
"voltage" | "volt" | "v" => Ok(ParamType::Voltage),
"time" | "t" | "s" => Ok(ParamType::Time),
"frequency" | "freq" | "hz" => Ok(ParamType::Frequency),
"boolean" | "bool" => Ok(ParamType::Bool),
"any" => Ok(ParamType::Any),
_ => Err(format!(
"'{}' is not a valid parameter type, the available types are: String, PinString, SpecValue, SpecVariable, ContextPins, OptionList, Int, long, UInt, Number, Current, Voltage, Time, Frequency, Bool, Any",
s.trim()
)),
}
}
}
#[cfg(test)]
mod tests {
use super::ParamType;
use std::str::FromStr;
#[test]
fn param_type_accepts_v93k_aliases() {
assert_eq!(ParamType::from_str("PinString").unwrap(), ParamType::String);
assert_eq!(
ParamType::from_str("pin_string").unwrap(),
ParamType::String
);
assert_eq!(ParamType::from_str("SpecValue").unwrap(), ParamType::String);
assert_eq!(
ParamType::from_str("spec_variable").unwrap(),
ParamType::String
);
assert_eq!(
ParamType::from_str("ContextPins").unwrap(),
ParamType::String
);
assert_eq!(
ParamType::from_str("OptionList").unwrap(),
ParamType::String
);
assert_eq!(ParamType::from_str("long").unwrap(), ParamType::Int);
}
}
#[derive(Debug, Clone, Serialize)]
pub enum Constraint {
In(Vec<ParamValue>),
GT(ParamValue),
GTE(ParamValue),
LT(ParamValue),
LTE(ParamValue),
}
impl Constraint {
pub fn is_satisfied(&self, value: &ParamValue) -> OrigenResult<()> {
match self {
Constraint::In(values) => {
if values.iter().any(|v| v == value) {
Ok(())
} else {
bail!(
"'{}' is not one of the permitted values: {}",
value,
values
.iter()
.map(|v| format!("'{}'", v))
.collect::<Vec<String>>()
.join(", ")
)
}
}
Constraint::GT(_) => Ok(()),
Constraint::GTE(_) => Ok(()),
Constraint::LT(_) => Ok(()),
Constraint::LTE(_) => Ok(()),
}
}
}