use crate::support::{
constraint::{Constrained, ConstraintError, NonNegative},
units::SpecificEnthalpy,
};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CompressionWork(SpecificEnthalpy);
impl CompressionWork {
#[must_use]
pub fn zero() -> Self {
Self::from_constrained(NonNegative::zero())
}
pub fn new(work: SpecificEnthalpy) -> Result<Self, ConstraintError> {
let work = NonNegative::new(work)?;
Ok(Self::from_constrained(work))
}
#[must_use]
pub fn from_constrained(work: Constrained<SpecificEnthalpy, NonNegative>) -> Self {
Self(work.into_inner())
}
#[must_use]
pub fn quantity(&self) -> SpecificEnthalpy {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ExpansionWork(SpecificEnthalpy);
impl ExpansionWork {
#[must_use]
pub fn zero() -> Self {
Self::from_constrained(NonNegative::zero())
}
pub fn new(work: SpecificEnthalpy) -> Result<Self, ConstraintError> {
let work = NonNegative::new(work)?;
Ok(Self::from_constrained(work))
}
#[must_use]
pub fn from_constrained(work: Constrained<SpecificEnthalpy, NonNegative>) -> Self {
Self(work.into_inner())
}
#[must_use]
pub fn quantity(&self) -> SpecificEnthalpy {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::support::constraint::NonNegative;
use crate::support::turbomachinery::test_utils::enth_si;
#[test]
fn compression_work_rejects_negative() {
let negative = enth_si(-1.0);
assert!(CompressionWork::new(negative).is_err());
}
#[test]
fn compression_work_from_constrained_quantity_roundtrip() {
let value = enth_si(42.0);
let constrained = NonNegative::new(value).unwrap();
let work = CompressionWork::from_constrained(constrained);
assert_eq!(work.quantity(), value);
}
#[test]
fn expansion_work_rejects_negative() {
let negative = enth_si(-1.0);
assert!(ExpansionWork::new(negative).is_err());
}
#[test]
fn expansion_work_from_constrained() {
let value = enth_si(5.0);
let constrained = NonNegative::new(value).unwrap();
let work = ExpansionWork::from_constrained(constrained);
assert_eq!(work.quantity(), value);
}
}