use std::any::Any;
use std::ops::{Add, Div, Mul, Neg, Sub};
use crate::physics::basic::{Coef, Power, PowerType, PhysicalQuantity, Energy, Velocity, Force,
time_delta_from_secs_f64, time_delta_to_secs_f64};
use approx::assert_relative_eq;
impl Default for Power {
fn default() -> Self {
Self::from_watt(0.0)
}
}
impl PhysicalQuantity for Power {
fn as_any(&self) -> &dyn Any {
self
}
fn is_zero(&self) -> bool {
self.v == 0.0
}
fn default_unit_value(&self) -> f64 {
self.as_watt()
}
fn set_value(&mut self, value: f64) {
self.v = value;
}
fn unit_display_name(&self) -> String {
"Power (W)".to_string()
}
}
impl Power {
pub fn from_watt(watt: f64) -> Self {
Self {
default_type: PowerType::Watt,
v: watt,
}
}
pub fn from_mill_watt(mill_watt: f64) -> Self {
Self {
default_type: PowerType::MillWatt,
v: mill_watt,
}
}
pub fn from_micro_watt(micro_watt: f64) -> Self {
Self {
default_type: PowerType::MicroWatt,
v: micro_watt,
}
}
pub fn from_nano_watt(nano_watt: f64) -> Self {
Self {
default_type: PowerType::NanoWatt,
v: nano_watt,
}
}
pub fn from_kilo_watt(kilo_watt: f64) -> Self {
Self {
default_type: PowerType::KiloWatt,
v: kilo_watt,
}
}
pub fn from_mega_watt(mega_watt: f64) -> Self {
Self {
default_type: PowerType::MegaWatt,
v: mega_watt,
}
}
pub fn from_horse_power(horse_power: f64) -> Self {
Self {
default_type: PowerType::HorsePower,
v: horse_power,
}
}
pub fn as_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v,
PowerType::MillWatt => self.v * 1e-3,
PowerType::MicroWatt => self.v * 1e-6,
PowerType::NanoWatt => self.v * 1e-9,
PowerType::KiloWatt => self.v * 1e3,
PowerType::MegaWatt => self.v * 1e6,
PowerType::HorsePower => self.v * 745.7, }
}
pub fn as_mill_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v * 1e3,
PowerType::MillWatt => self.v,
PowerType::MicroWatt => self.v * 1e-3,
PowerType::NanoWatt => self.v * 1e-6,
PowerType::KiloWatt => self.v * 1e6,
PowerType::MegaWatt => self.v * 1e9,
PowerType::HorsePower => self.v * 745700.0,
}
}
pub fn as_micro_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v * 1e6,
PowerType::MillWatt => self.v * 1e3,
PowerType::MicroWatt => self.v,
PowerType::NanoWatt => self.v * 1e-3,
PowerType::KiloWatt => self.v * 1e9,
PowerType::MegaWatt => self.v * 1e12,
PowerType::HorsePower => self.v * 745700000.0,
}
}
pub fn as_nano_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v * 1e9,
PowerType::MillWatt => self.v * 1e6,
PowerType::MicroWatt => self.v * 1e3,
PowerType::NanoWatt => self.v,
PowerType::KiloWatt => self.v * 1e12,
PowerType::MegaWatt => self.v * 1e15,
PowerType::HorsePower => self.v * 745700000000.0,
}
}
pub fn as_kilo_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v * 1e-3,
PowerType::MillWatt => self.v * 1e-6,
PowerType::MicroWatt => self.v * 1e-9,
PowerType::NanoWatt => self.v * 1e-12,
PowerType::KiloWatt => self.v,
PowerType::MegaWatt => self.v * 1e3,
PowerType::HorsePower => self.v * 0.7457,
}
}
pub fn as_mega_watt(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v * 1e-6,
PowerType::MillWatt => self.v * 1e-9,
PowerType::MicroWatt => self.v * 1e-12,
PowerType::NanoWatt => self.v * 1e-15,
PowerType::KiloWatt => self.v * 1e-3,
PowerType::MegaWatt => self.v,
PowerType::HorsePower => self.v * 0.0007457,
}
}
pub fn as_horse_power(&self) -> f64 {
match self.default_type {
PowerType::Watt => self.v / 745.7,
PowerType::MillWatt => self.v / 745700.0,
PowerType::MicroWatt => self.v / 745700000.0,
PowerType::NanoWatt => self.v / 745700000000.0,
PowerType::KiloWatt => self.v / 0.7457,
PowerType::MegaWatt => self.v / 0.0007457,
PowerType::HorsePower => self.v,
}
}
}
impl Add for Power {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
let v = self.as_watt() + rhs.as_watt();
Self::from_watt(v)
}
}
impl<'a, 'b> Add<&'b Power> for &'a Power {
type Output = Power;
fn add(self, rhs: &'b Power) -> Self::Output { Power::from_watt(self.as_watt() + rhs.as_watt()) }
}
impl<'a> Add<&'a Power> for Power {
type Output = Power;
fn add(self, rhs: &'a Power) -> Self::Output { Power::from_watt(self.as_watt() + rhs.as_watt()) }
}
impl<'a> Add<Power> for &'a Power {
type Output = Power;
fn add(self, rhs: Power) -> Self::Output { Power::from_watt(self.as_watt() + rhs.as_watt()) }
}
impl Add<f64> for Power {
type Output = Self;
fn add(self, rhs: f64) -> Self::Output {
let v = self.v + rhs;
Power {
v,
default_type: self.default_type,
}
}
}
impl Sub for Power {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
let v = self.as_watt() - rhs.as_watt();
Self::from_watt(v)
}
}
impl<'a, 'b> Sub<&'b Power> for &'a Power {
type Output = Power;
fn sub(self, rhs: &'b Power) -> Self::Output { Power::from_watt(self.as_watt() - rhs.as_watt()) }
}
impl<'a> Sub<&'a Power> for Power {
type Output = Power;
fn sub(self, rhs: &'a Power) -> Self::Output { Power::from_watt(self.as_watt() - rhs.as_watt()) }
}
impl<'a> Sub<Power> for &'a Power {
type Output = Power;
fn sub(self, rhs: Power) -> Self::Output { Power::from_watt(self.as_watt() - rhs.as_watt()) }
}
impl Sub<f64> for Power {
type Output = Self;
fn sub(self, rhs: f64) -> Self::Output {
let v = self.v - rhs;
Power {
v,
default_type: self.default_type,
}
}
}
impl Mul<f64> for Power {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
let v = self.as_watt() * rhs;
Self::from_watt(v)
}
}
impl Div<f64> for Power {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
let v = self.as_watt() / rhs;
Self::from_watt(v)
}
}
impl Mul<Power> for f64 {
type Output = Power;
fn mul(self, rhs: Power) -> Self::Output {
let v = self * rhs.as_watt();
Power::from_watt(v)
}
}
impl Div<Power> for f64 {
type Output = Power;
fn div(self, rhs: Power) -> Self::Output {
let v = self / rhs.as_watt();
Power::from_watt(v)
}
}
impl Mul<Coef> for Power {
type Output = Self;
fn mul(self, rhs: Coef) -> Self::Output {
let v = self.as_watt() * rhs.get_value();
Self::from_watt(v)
}
}
impl Div<Coef> for Power {
type Output = Self;
fn div(self, rhs: Coef) -> Self::Output {
let v = self.as_watt() / rhs.get_value();
Self::from_watt(v)
}
}
impl Neg for Power {
type Output = Self;
fn neg(self) -> Self::Output {
let v = -self.as_watt();
Self::from_watt(v)
}
}
impl Div<Force> for Power {
type Output = Velocity;
fn div(self, rhs: Force) -> Self::Output {
let velocity_value = self.as_watt() / rhs.as_newton();
Velocity::from_m_per_sec(velocity_value)
}
}
impl<'a, 'b> Div<&'b Force> for &'a Power {
type Output = Velocity;
fn div(self, rhs: &'b Force) -> Self::Output { Velocity::from_m_per_sec(self.as_watt() / rhs.as_newton()) }
}
impl<'a> Div<&'a Force> for Power {
type Output = Velocity;
fn div(self, rhs: &'a Force) -> Self::Output { Velocity::from_m_per_sec(self.as_watt() / rhs.as_newton()) }
}
impl<'a> Div<Force> for &'a Power {
type Output = Velocity;
fn div(self, rhs: Force) -> Self::Output { Velocity::from_m_per_sec(self.as_watt() / rhs.as_newton()) }
}
impl Div<Velocity> for Power {
type Output = Force;
fn div(self, rhs: Velocity) -> Self::Output {
let force_value = self.as_watt() / rhs.as_m_per_sec();
Force::from_newton(force_value)
}
}
impl<'a, 'b> Div<&'b Velocity> for &'a Power {
type Output = Force;
fn div(self, rhs: &'b Velocity) -> Self::Output { Force::from_newton(self.as_watt() / rhs.as_m_per_sec()) }
}
impl<'a> Div<&'a Velocity> for Power {
type Output = Force;
fn div(self, rhs: &'a Velocity) -> Self::Output { Force::from_newton(self.as_watt() / rhs.as_m_per_sec()) }
}
impl<'a> Div<Velocity> for &'a Power {
type Output = Force;
fn div(self, rhs: Velocity) -> Self::Output { Force::from_newton(self.as_watt() / rhs.as_m_per_sec()) }
}
impl Mul<std::time::Duration> for Power {
type Output = Energy; fn mul(self, rhs: std::time::Duration) -> Self::Output {
let energy_value = self.as_watt() * rhs.as_secs_f64();
Energy::from_joule(energy_value)
}
}
impl Mul<chrono::TimeDelta> for Power {
type Output = Energy; fn mul(self, rhs: chrono::TimeDelta) -> Self::Output {
let energy_value = self.as_watt() * time_delta_to_secs_f64(&rhs);
Energy::from_joule(energy_value)
}
}
impl Mul<Power> for std::time::Duration {
type Output = Energy; fn mul(self, rhs: Power) -> Self::Output {
let energy_value = self.as_secs_f64() * rhs.as_watt();
Energy::from_joule(energy_value)
}
}
impl Mul<Power> for chrono::TimeDelta {
type Output = Energy; fn mul(self, rhs: Power) -> Self::Output {
let energy_value = time_delta_to_secs_f64(&self) * rhs.as_watt();
Energy::from_joule(energy_value)
}
}
impl Mul<Velocity> for Force {
type Output = Power; fn mul(self, rhs: Velocity) -> Self::Output {
let power_value = self.as_newton() * rhs.as_m_per_sec();
Power::from_watt(power_value)
}
}
impl Mul<Force> for Velocity {
type Output = Power; fn mul(self, rhs: Force) -> Self::Output {
let power_value = self.as_m_per_sec() * rhs.as_newton();
Power::from_watt(power_value)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::physics::basic::{Energy, Force, Velocity};
use std::time::Duration;
#[test]
fn test_power() {
let p1 = Power::from_watt(1.0); let p2 = Power::from_mill_watt(1000.0); let p3 = Power::from_micro_watt(1000000.0); let p4 = Power::from_nano_watt(1000000000.0); let p5 = Power::from_kilo_watt(0.001); let p6 = Power::from_mega_watt(0.000001); let p7 = Power::from_horse_power(1.0 / 745.7);
assert_relative_eq!(p1.as_watt(), 1.0);
assert_relative_eq!(p2.as_watt(), 1.0);
assert_relative_eq!(p3.as_watt(), 1.0);
assert_relative_eq!(p4.as_watt(), 1.0);
assert_relative_eq!(p5.as_watt(), 1.0);
assert_relative_eq!(p6.as_watt(), 1.0);
assert_relative_eq!(p7.as_watt(), 1.0, epsilon = 1e-10);
}
#[test]
fn test_power_as() {
let p = Power::from_watt(1.0);
assert_relative_eq!(p.as_mill_watt(), 1000.0);
assert_relative_eq!(p.as_micro_watt(), 1000000.0);
assert_relative_eq!(p.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p.as_kilo_watt(), 0.001);
assert_relative_eq!(p.as_mega_watt(), 0.000001);
assert_relative_eq!(p.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
}
#[test]
fn test_power_add() {
let p1 = Power::from_watt(5.0);
let p2 = Power::from_mill_watt(3000.0); let result = p1 + p2;
assert_relative_eq!(result.as_watt(), 8.0);
}
#[test]
fn test_power_sub() {
let p1 = Power::from_watt(10.0);
let p2 = Power::from_mill_watt(2000.0); let result = p1 - p2;
assert_relative_eq!(result.as_watt(), 8.0);
}
#[test]
fn test_power_mul() {
let p = Power::from_watt(5.0);
let result = p * 3.0;
assert_relative_eq!(result.as_watt(), 15.0);
}
#[test]
fn test_power_div() {
let p = Power::from_watt(15.0);
let result = p / 3.0;
assert_relative_eq!(result.as_watt(), 5.0);
}
#[test]
fn test_power_mul_duration() {
let power = Power::from_watt(100.0); let time = Duration::from_secs(5); let energy: Energy = power * time;
assert_relative_eq!(energy.as_joule(), 500.0);
}
#[test]
fn test_power_mul_timedelta() {
let power = Power::from_watt(100.0); let td = time_delta_from_secs_f64(5.0);
let energy: Energy = power * td;
assert_relative_eq!(energy.as_joule(), 500.0);
let neg_td = time_delta_from_secs_f64(-5.0);
let energy_neg: Energy = power * neg_td;
assert_relative_eq!(energy_neg.as_joule(), -500.0);
let energy_comm: Energy = td * power;
assert_relative_eq!(energy_comm.as_joule(), 500.0);
}
#[test]
fn test_duration_mul_power() {
let time = Duration::from_secs(5); let power = Power::from_watt(100.0); let energy: Energy = time * power;
assert_relative_eq!(energy.as_joule(), 500.0);
}
#[test]
fn test_force_mul_velocity() {
let force = Force::from_newton(10.0); let velocity = Velocity::from_m_per_sec(5.0); let power: Power = force * velocity;
assert_relative_eq!(power.as_watt(), 50.0);
}
#[test]
fn test_velocity_mul_force() {
let velocity = Velocity::from_m_per_sec(5.0); let force = Force::from_newton(10.0); let power: Power = velocity * force;
assert_relative_eq!(power.as_watt(), 50.0);
}
#[test]
fn test_horse_power_conversion() {
let hp = Power::from_horse_power(1.0); assert_relative_eq!(hp.as_watt(), 745.7, epsilon = 1e-10);
let watt = Power::from_watt(745.7); assert_relative_eq!(watt.as_horse_power(), 1.0, epsilon = 1e-10);
}
#[test]
fn test_default_unit_value() {
let p = Power::from_watt(5.0);
assert_relative_eq!(p.default_unit_value(), 5.0);
}
#[test]
fn test_is_zero() {
let p1 = Power::from_watt(0.0);
let p2 = Power::from_watt(1.0);
assert!(p1.is_zero());
assert!(!p2.is_zero());
}
#[test]
fn test_set_value() {
let mut p = Power::from_watt(5.0);
p.set_value(10.0);
assert_relative_eq!(p.as_watt(), 10.0);
}
#[test]
fn test_power_div_force() {
let power = Power::from_watt(50.0); let force = Force::from_newton(10.0); let velocity: Velocity = power / force;
assert_relative_eq!(velocity.as_m_per_sec(), 5.0);
}
#[test]
fn test_power_div_velocity() {
let power = Power::from_watt(50.0); let velocity = Velocity::from_m_per_sec(5.0); let force: Force = power / velocity;
assert_relative_eq!(force.as_newton(), 10.0);
}
#[test]
fn test_power_comprehensive_as_methods() {
let p_watt = Power::from_watt(1.0);
assert_relative_eq!(p_watt.as_watt(), 1.0);
assert_relative_eq!(p_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_mill_watt = Power::from_mill_watt(1000.0);
assert_relative_eq!(p_mill_watt.as_watt(), 1.0);
assert_relative_eq!(p_mill_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_mill_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_mill_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_mill_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_mill_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_mill_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_micro_watt = Power::from_micro_watt(1000000.0);
assert_relative_eq!(p_micro_watt.as_watt(), 1.0);
assert_relative_eq!(p_micro_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_micro_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_micro_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_micro_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_micro_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_micro_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_nano_watt = Power::from_nano_watt(1000000000.0);
assert_relative_eq!(p_nano_watt.as_watt(), 1.0);
assert_relative_eq!(p_nano_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_nano_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_nano_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_nano_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_nano_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_nano_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_kilo_watt = Power::from_kilo_watt(0.001);
assert_relative_eq!(p_kilo_watt.as_watt(), 1.0);
assert_relative_eq!(p_kilo_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_kilo_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_kilo_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_kilo_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_kilo_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_kilo_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_mega_watt = Power::from_mega_watt(0.000001);
assert_relative_eq!(p_mega_watt.as_watt(), 1.0);
assert_relative_eq!(p_mega_watt.as_mill_watt(), 1000.0);
assert_relative_eq!(p_mega_watt.as_micro_watt(), 1000000.0);
assert_relative_eq!(p_mega_watt.as_nano_watt(), 1000000000.0);
assert_relative_eq!(p_mega_watt.as_kilo_watt(), 0.001);
assert_relative_eq!(p_mega_watt.as_mega_watt(), 0.000001);
assert_relative_eq!(p_mega_watt.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
let p_horse_power = Power::from_horse_power(1.0 / 745.7);
assert_relative_eq!(p_horse_power.as_watt(), 1.0, epsilon = 1e-10);
assert_relative_eq!(p_horse_power.as_mill_watt(), 1000.0, epsilon = 1e-7);
assert_relative_eq!(p_horse_power.as_micro_watt(), 1000000.0, epsilon = 1e-4);
assert_relative_eq!(p_horse_power.as_nano_watt(), 1000000000.0, epsilon = 1e-1);
assert_relative_eq!(p_horse_power.as_kilo_watt(), 0.001, epsilon = 1e-13);
assert_relative_eq!(p_horse_power.as_mega_watt(), 0.000001, epsilon = 1e-16);
assert_relative_eq!(p_horse_power.as_horse_power(), 1.0 / 745.7, epsilon = 1e-10);
}
#[test]
fn test_power_comprehensive_arithmetic_operations() {
let p_watt = Power::from_watt(10.0);
let result = p_watt + 5.0;
assert_relative_eq!(result.as_watt(), 15.0);
let p_mill_watt = Power::from_mill_watt(10000.0);
let result = p_mill_watt + 5000.0;
assert_relative_eq!(result.as_mill_watt(), 15000.0);
let p_micro_watt = Power::from_micro_watt(10000000.0);
let result = p_micro_watt + 5000000.0;
assert_relative_eq!(result.as_micro_watt(), 15000000.0);
let p_nano_watt = Power::from_nano_watt(10000000000.0);
let result = p_nano_watt + 5000000000.0;
assert_relative_eq!(result.as_nano_watt(), 15000000000.0);
let p_kilo_watt = Power::from_kilo_watt(0.01);
let result = p_kilo_watt + 0.005;
assert_relative_eq!(result.as_kilo_watt(), 0.015);
let p_mega_watt = Power::from_mega_watt(0.00001);
let result = p_mega_watt + 0.000005;
assert_relative_eq!(result.as_mega_watt(), 0.000015);
let p_horse_power = Power::from_horse_power(0.01);
let result = p_horse_power + 0.005;
assert_relative_eq!(result.as_horse_power(), 0.015);
let p_watt = Power::from_watt(20.0);
let result = p_watt - 5.0;
assert_relative_eq!(result.as_watt(), 15.0);
let p_mill_watt = Power::from_mill_watt(20000.0);
let result = p_mill_watt - 5000.0;
assert_relative_eq!(result.as_mill_watt(), 15000.0);
let p_micro_watt = Power::from_micro_watt(20000000.0);
let result = p_micro_watt - 5000000.0;
assert_relative_eq!(result.as_micro_watt(), 15000000.0);
let p_nano_watt = Power::from_nano_watt(20000000000.0);
let result = p_nano_watt - 5000000000.0;
assert_relative_eq!(result.as_nano_watt(), 15000000000.0);
let p_kilo_watt = Power::from_kilo_watt(0.02);
let result = p_kilo_watt - 0.005;
assert_relative_eq!(result.as_kilo_watt(), 0.015);
let p_mega_watt = Power::from_mega_watt(0.00002);
let result = p_mega_watt - 0.000005;
assert_relative_eq!(result.as_mega_watt(), 0.000015);
let p_horse_power = Power::from_horse_power(0.02);
let result = p_horse_power - 0.005;
assert_relative_eq!(result.as_horse_power(), 0.015);
}
#[test]
fn test_power_multiplication_operations() {
let p_watt = Power::from_watt(10.0);
let result = p_watt * 2.0;
assert_relative_eq!(result.as_watt(), 20.0);
let p_mill_watt = Power::from_mill_watt(1000.0);
let result = p_mill_watt * 3.0;
assert_relative_eq!(result.as_watt(), 3.0);
let p_micro_watt = Power::from_micro_watt(1000000.0);
let result = p_micro_watt * 2.5;
assert_relative_eq!(result.as_watt(), 2.5);
let p_nano_watt = Power::from_nano_watt(1000000000.0);
let result = p_nano_watt * 1.5;
assert_relative_eq!(result.as_watt(), 1.5);
let p_kilo_watt = Power::from_kilo_watt(0.001);
let result = p_kilo_watt * 2.0;
assert_relative_eq!(result.as_watt(), 2.0);
let p_mega_watt = Power::from_mega_watt(0.000001);
let result = p_mega_watt * 3.0;
assert_relative_eq!(result.as_watt(), 3.0);
let p_horse_power = Power::from_horse_power(1.0 / 745.7);
let result = p_horse_power * 4.0;
assert_relative_eq!(result.as_watt(), 4.0, epsilon = 1e-10);
}
#[test]
fn test_power_division_operations() {
let p_watt = Power::from_watt(20.0);
let result = p_watt / 2.0;
assert_relative_eq!(result.as_watt(), 10.0);
let p_mill_watt = Power::from_mill_watt(3000.0);
let result = p_mill_watt / 3.0;
assert_relative_eq!(result.as_watt(), 1.0);
let p_micro_watt = Power::from_micro_watt(2500000.0);
let result = p_micro_watt / 2.5;
assert_relative_eq!(result.as_watt(), 1.0);
let p_nano_watt = Power::from_nano_watt(1500000000.0);
let result = p_nano_watt / 1.5;
assert_relative_eq!(result.as_watt(), 1.0);
let p_kilo_watt = Power::from_kilo_watt(0.002);
let result = p_kilo_watt / 2.0;
assert_relative_eq!(result.as_watt(), 1.0);
let p_mega_watt = Power::from_mega_watt(0.000003);
let result = p_mega_watt / 3.0;
assert_relative_eq!(result.as_watt(), 1.0);
let p_horse_power = Power::from_horse_power(4.0 / 745.7);
let result = p_horse_power / 4.0;
assert_relative_eq!(result.as_watt(), 1.0, epsilon = 1e-10);
}
#[test]
fn test_power_coef_operations() {
let p = Power::from_watt(10.0);
let coef = Coef::new(2.0);
let result = p * coef;
assert_relative_eq!(result.as_watt(), 20.0);
let result = p / coef;
assert_relative_eq!(result.as_watt(), 5.0);
let p_horse_power = Power::from_horse_power(1.0);
let coef = Coef::new(3.0);
let result = p_horse_power * coef;
assert_relative_eq!(result.as_watt(), 2237.1, epsilon = 1e-10);
}
#[test]
fn test_power_edge_cases_arithmetic() {
let zero_power = Power::from_watt(0.0);
let result = zero_power + 10.0;
assert_relative_eq!(result.as_watt(), 10.0);
let result = zero_power - 5.0;
assert_relative_eq!(result.as_watt(), -5.0);
let result = zero_power * 100.0;
assert_relative_eq!(result.as_watt(), 0.0);
let negative_power = Power::from_watt(-10.0);
let result = negative_power + 15.0;
assert_relative_eq!(result.as_watt(), 5.0);
let result = negative_power - 5.0;
assert_relative_eq!(result.as_watt(), -15.0);
let result = negative_power * 2.0;
assert_relative_eq!(result.as_watt(), -20.0);
let large_power = Power::from_mega_watt(1000.0);
let result = large_power * 2.0;
assert_relative_eq!(result.as_watt(), 2e9);
let small_power = Power::from_nano_watt(1.0);
let result = small_power * 1000.0;
assert_relative_eq!(result.as_watt(), 1e-6);
}
#[test]
fn test_default(){
let a = Power::default();
assert_relative_eq!(a.v,0.0);
assert_eq!(a.default_type,PowerType::Watt);
}
#[test]
fn test_f64_mul_power() {
let p_watt = Power::from_watt(10.0);
let result = 2.0 * p_watt;
assert_relative_eq!(result.as_watt(), 20.0);
let p_mill_watt = Power::from_mill_watt(1000.0);
let result = 3.0 * p_mill_watt;
assert_relative_eq!(result.as_watt(), 3.0);
let p_micro_watt = Power::from_micro_watt(1000000.0);
let result = 2.5 * p_micro_watt;
assert_relative_eq!(result.as_watt(), 2.5);
let p_nano_watt = Power::from_nano_watt(1000000000.0);
let result = 1.5 * p_nano_watt;
assert_relative_eq!(result.as_watt(), 1.5);
let p_kilo_watt = Power::from_kilo_watt(0.001);
let result = 2.0 * p_kilo_watt;
assert_relative_eq!(result.as_watt(), 2.0);
let p_mega_watt = Power::from_mega_watt(0.000001);
let result = 3.0 * p_mega_watt;
assert_relative_eq!(result.as_watt(), 3.0);
let p_horse_power = Power::from_horse_power(1.0 / 745.7);
let result = 4.0 * p_horse_power;
assert_relative_eq!(result.as_watt(), 4.0, epsilon = 1e-10);
let p_negative = Power::from_watt(-5.0);
let result = 3.0 * p_negative;
assert_relative_eq!(result.as_watt(), -15.0);
let p_zero = Power::from_watt(0.0);
let result = 100.0 * p_zero;
assert_relative_eq!(result.as_watt(), 0.0);
}
#[test]
fn test_f64_div_power() {
let p_watt = Power::from_watt(20.0);
let result = 40.0 / p_watt;
assert_relative_eq!(result.as_watt(), 2.0);
let p_mill_watt = Power::from_mill_watt(3000.0);
let result = 3.0 / p_mill_watt;
assert_relative_eq!(result.as_watt(), 1.0);
let p_micro_watt = Power::from_micro_watt(2500000.0);
let result = 2.5 / p_micro_watt;
assert_relative_eq!(result.as_watt(), 1.0);
let p_nano_watt = Power::from_nano_watt(1500000000.0);
let result = 1.5 / p_nano_watt;
assert_relative_eq!(result.as_watt(), 1.0);
let p_kilo_watt = Power::from_kilo_watt(0.002);
let result = 2.0 / p_kilo_watt;
assert_relative_eq!(result.as_watt(), 1.0);
let p_mega_watt = Power::from_mega_watt(0.000003);
let result = 3.0 / p_mega_watt;
assert_relative_eq!(result.as_watt(), 1.0);
let p_horse_power = Power::from_horse_power(4.0 / 745.7);
let result = 4.0 / p_horse_power;
assert_relative_eq!(result.as_watt(), 1.0, epsilon = 1e-10);
let p_negative = Power::from_watt(-10.0);
let result = 30.0 / p_negative;
assert_relative_eq!(result.as_watt(), -3.0);
let p_zero = Power::from_watt(0.0);
}
#[test]
fn test_power_comprehensive_multiplication_division() {
let units = vec![
(Power::from_watt(10.0), "Watt"),
(Power::from_mill_watt(10000.0), "MillWatt"),
(Power::from_micro_watt(10000000.0), "MicroWatt"),
(Power::from_nano_watt(10000000000.0), "NanoWatt"),
(Power::from_kilo_watt(0.01), "KiloWatt"),
(Power::from_mega_watt(0.00001), "MegaWatt"),
(Power::from_horse_power(10.0 / 745.7), "HorsePower"),
];
for (power, unit_name) in units {
let result1 = power * 2.0;
assert_relative_eq!(result1.as_watt(), 20.0, epsilon = 1e-10);
let result2 = 2.0 * power;
assert_relative_eq!(result2.as_watt(), 20.0, epsilon = 1e-10);
let result3 = power / 2.0;
assert_relative_eq!(result3.as_watt(), 5.0, epsilon = 1e-10);
let result4 = 10.0 / power;
assert_relative_eq!(result4.as_watt(), 1.0, epsilon = 1e-10);
}
let p = Power::from_watt(15.0);
let coef = Coef::new(3.0);
let result_mul = p * coef;
assert_relative_eq!(result_mul.as_watt(), 45.0);
let result_div = p / coef;
assert_relative_eq!(result_div.as_watt(), 5.0);
let power = Power::from_watt(100.0);
let force = Force::from_newton(20.0);
let velocity = Velocity::from_m_per_sec(5.0);
let result_velocity = power / force;
assert_relative_eq!(result_velocity.as_m_per_sec(), 5.0);
let result_force = power / velocity;
assert_relative_eq!(result_force.as_newton(), 20.0);
let result_power1 = force * velocity;
assert_relative_eq!(result_power1.as_watt(), 100.0);
let result_power2 = velocity * force;
assert_relative_eq!(result_power2.as_watt(), 100.0);
let time = Duration::from_secs(2);
let energy = power * time;
assert_relative_eq!(energy.as_joule(), 200.0);
let energy2 = time * power;
assert_relative_eq!(energy2.as_joule(), 200.0);
}
#[test]
fn test_power_ref_ops() {
let p1 = Power::from_watt(10.0);
let p2 = Power::from_kilo_watt(0.005); let s = &p1 + &p2;
assert_relative_eq!(s.as_watt(), 15.0);
let d = &p1 - &p2;
assert_relative_eq!(d.as_watt(), 5.0);
let v = &p1 / &Force::from_newton(2.0);
assert_relative_eq!(v.as_m_per_sec(), 5.0);
let f = &p1 / &Velocity::from_m_per_sec(2.0);
assert_relative_eq!(f.as_newton(), 5.0);
let s2 = p1 + &p2;
assert_relative_eq!(s2.as_watt(), 15.0);
let p1b = Power::from_watt(10.0);
let s3 = &p1b + p2;
assert_relative_eq!(s3.as_watt(), 15.0);
let p1c = Power::from_watt(10.0);
let p2c = Power::from_kilo_watt(0.005);
let d2 = p1c - &p2c;
assert_relative_eq!(d2.as_watt(), 5.0);
let p1d = Power::from_watt(10.0);
let p2d = Power::from_kilo_watt(0.005);
let d3 = &p1d - p2d;
assert_relative_eq!(d3.as_watt(), 5.0);
let v2 = p1 / &Force::from_newton(2.0);
assert_relative_eq!(v2.as_m_per_sec(), 5.0);
let p1e = Power::from_watt(10.0);
let v3 = &p1e / Force::from_newton(2.0);
assert_relative_eq!(v3.as_m_per_sec(), 5.0);
let f2 = p1 / &Velocity::from_m_per_sec(2.0);
assert_relative_eq!(f2.as_newton(), 5.0);
let p1f = Power::from_watt(10.0);
let f3 = &p1f / Velocity::from_m_per_sec(2.0);
assert_relative_eq!(f3.as_newton(), 5.0);
}
#[test]
fn test_power_neg() {
let p1 = Power::from_watt(5.0);
let neg_p1 = -p1;
assert_relative_eq!(neg_p1.as_watt(), -5.0);
let p2 = Power::from_kilo_watt(-10.0);
let neg_p2 = -p2;
assert_relative_eq!(neg_p2.as_kilo_watt(), 10.0);
let p3 = Power::from_watt(0.0);
let neg_p3 = -p3;
assert_relative_eq!(neg_p3.as_watt(), 0.0);
let p4 = Power::from_mega_watt(1.0);
let neg_p4 = -p4;
assert_relative_eq!(neg_p4.as_watt(), -1_000_000.0);
let p5 = Power::from_horse_power(1.0);
let neg_p5 = -p5;
assert_relative_eq!(neg_p5.as_watt(), -745.7);
}
}