use super::try_from;
#[derive(
Copy,
Clone,
Debug,
Eq,
PartialEq,
strum_macros::AsRefStr,
strum_macros::EnumString,
strum_macros::FromRepr,
strum_macros::IntoStaticStr,
)]
#[strum(ascii_case_insensitive)]
#[repr(u8)]
pub enum Phase {
#[strum(to_string = "phase_liquid", serialize = "liquid")]
Liquid = 0,
#[strum(to_string = "phase_supercritical", serialize = "supercritical")]
Supercritical = 1,
#[strum(
to_string = "phase_supercritical_gas",
serialize = "supercritical_gas",
serialize = "SupercriticalGas"
)]
SupercriticalGas = 2,
#[strum(
to_string = "phase_supercritical_liquid",
serialize = "supercritical_liquid",
serialize = "SupercriticalLiquid"
)]
SupercriticalLiquid = 3,
#[strum(
to_string = "phase_critical_point",
serialize = "critical_point",
serialize = "CriticalPoint"
)]
CriticalPoint = 4,
#[strum(to_string = "phase_gas", serialize = "gas")]
Gas = 5,
#[strum(
to_string = "phase_twophase",
serialize = "phase_two_phase",
serialize = "two_phase",
serialize = "TwoPhase"
)]
TwoPhase = 6,
#[strum(to_string = "phase_unknown", serialize = "unknown")]
Unknown = 7,
#[strum(to_string = "phase_not_imposed", serialize = "not_imposed", serialize = "NotImposed")]
NotImposed = 8,
}
impl From<Phase> for u8 {
fn from(value: Phase) -> Self {
value as u8
}
}
impl TryFrom<u8> for Phase {
type Error = strum::ParseError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Phase::from_repr(value).ok_or(strum::ParseError::VariantNotFound)
}
}
impl TryFrom<f64> for Phase {
type Error = strum::ParseError;
fn try_from(value: f64) -> Result<Self, Self::Error> {
try_from(value)
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use rstest::*;
use super::{Phase::*, *};
#[rstest]
#[case(Liquid, "phase_liquid")]
#[case(Supercritical, "phase_supercritical")]
#[case(SupercriticalGas, "phase_supercritical_gas")]
#[case(SupercriticalLiquid, "phase_supercritical_liquid")]
#[case(CriticalPoint, "phase_critical_point")]
#[case(Gas, "phase_gas")]
#[case(TwoPhase, "phase_twophase")]
#[case(Unknown, "phase_unknown")]
#[case(NotImposed, "phase_not_imposed")]
fn as_str(#[case] sut: Phase, #[case] expected: &str) {
let str = sut.as_ref();
let static_str: &'static str = sut.into();
assert_eq!(str, expected);
assert_eq!(static_str, expected);
}
#[rstest]
#[case(vec!["phase_liquid", "liquid"], Liquid)]
#[case(vec!["phase_supercritical", "supercritical"], Supercritical)]
#[case(vec!["phase_supercritical_gas", "supercritical_gas", "SupercriticalGas"], SupercriticalGas)]
#[case(vec!["phase_supercritical_liquid", "supercritical_liquid", "SupercriticalLiquid"], SupercriticalLiquid)]
#[case(vec!["phase_critical_point", "critical_point", "CriticalPoint"], CriticalPoint)]
#[case(vec!["phase_gas", "gas"], Gas)]
#[case(vec!["phase_twophase", "phase_two_phase", "two_phase", "TwoPhase"], TwoPhase)]
#[case(vec!["phase_unknown", "unknown"], Unknown)]
#[case(vec!["phase_not_imposed", "not_imposed", "NotImposed"], NotImposed)]
fn from_valid_str(#[case] valid: Vec<&str>, #[case] expected: Phase) {
for s in valid {
let res1 = Phase::from_str(s).unwrap();
let res2 = Phase::try_from(s).unwrap();
assert_eq!(res1, expected);
assert_eq!(res2, expected);
}
}
#[rstest]
#[case("")]
#[case("Hello, World!")]
fn from_invalid_str(#[case] invalid: &str) {
let res1 = Phase::from_str(invalid);
let res2 = Phase::try_from(invalid);
assert!(res1.is_err());
assert!(res2.is_err());
}
#[rstest]
#[case(Liquid, 0)]
#[case(Supercritical, 1)]
#[case(SupercriticalGas, 2)]
#[case(SupercriticalLiquid, 3)]
#[case(CriticalPoint, 4)]
#[case(Gas, 5)]
#[case(TwoPhase, 6)]
#[case(Unknown, 7)]
#[case(NotImposed, 8)]
fn into_u8(#[case] sut: Phase, #[case] expected: u8) {
let res: u8 = sut.into();
assert_eq!(res, expected);
}
#[rstest]
#[case(0, Liquid)]
#[case(1, Supercritical)]
#[case(2, SupercriticalGas)]
#[case(3, SupercriticalLiquid)]
#[case(4, CriticalPoint)]
#[case(5, Gas)]
#[case(6, TwoPhase)]
#[case(7, Unknown)]
#[case(8, NotImposed)]
fn try_from_valid_u8_or_f64(#[case] valid: u8, #[case] expected: Phase) {
let res1 = Phase::try_from(valid).unwrap();
let res2 = Phase::try_from(f64::from(valid)).unwrap();
assert_eq!(res1, expected);
assert_eq!(res2, expected);
}
#[rstest]
#[case(254)]
#[case(255)]
fn try_from_invalid_u8(#[case] invalid: u8) {
let res = Phase::try_from(invalid);
assert!(res.is_err());
}
#[rstest]
#[case(-1.0)]
#[case(255.0)]
#[case(100e3)]
fn try_from_invalid_f64(#[case] invalid: f64) {
let res = Phase::try_from(invalid);
assert!(res.is_err());
}
}