Files
bqst/bqst-core/src/unit.rs
2025-12-21 15:38:31 +01:00

104 lines
2.6 KiB
Rust

use std::ops::{DivAssign, MulAssign};
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Unit {
Ampere,
Watt,
Volt,
Ohm,
None,
}
use Unit::*;
#[derive(Debug)]
pub struct UnknownUnit;
impl TryFrom<Unit> for char {
type Error = UnknownUnit;
fn try_from(value: Unit) -> Result<Self, Self::Error> {
match value {
Ampere => Ok('A'),
Watt => Ok('W'),
Volt => Ok('V'),
Ohm => Ok('Ω'),
None => Err(UnknownUnit),
}
}
}
impl TryFrom<char> for Unit {
type Error = UnknownUnit;
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'V' => Ok(Volt),
'A' => Ok(Ampere),
'W' => Ok(Watt),
'Ω' => Ok(Ohm),
_ => Err(UnknownUnit),
}
}
}
impl TryFrom<&str> for Unit {
type Error = ();
fn try_from(value: &str) -> Result<Self, Self::Error> {
match value {
"V" | "volt" | "volts" => Ok(Volt),
"A" | "amp" | "amps" | "ampere" | "amperes" => Ok(Ampere),
"W" | "watt" | "watts" => Ok(Watt),
"" | "ohm" | "ohms" => Ok(Ohm),
"" => Ok(None),
_ => Err(()),
}
}
}
impl MulAssign<Unit> for Unit {
fn mul_assign(&mut self, rhs: Unit) {
*self = match (*self, rhs) {
(Ampere, Volt) | (Volt, Ampere) => Watt,
(Ampere, Ohm) | (Ohm, Ampere) => Volt,
(Watt, _) | (_, Watt) | (Ampere, Ampere) | (Volt, Volt) | (Ohm, Ohm) => {
panic!("Unavailable unit")
}
(Volt, Ohm) | (Ohm, Volt) => panic!("Unknown unit"),
(t, None) => t,
(None, t) => t,
}
}
}
impl DivAssign<Unit> for Unit {
fn div_assign(&mut self, rhs: Unit) {
*self = match (*self, rhs) {
(t, None) => t,
// FIXME: bodge to allow calculating parallel circuit
// resistance (1 / sum(1 / R_i))
(None, Ohm) => Ohm,
(None, _) => panic!("idk the inverse of any of the types"),
(a, b) if a == b => None,
(Ampere, Ampere) | (Watt, Watt) | (Volt, Volt) | (Ohm, Ohm) => None,
(Watt, Ampere) => Volt,
(Watt, Volt) => Ampere,
(Volt, Ampere) => Ohm,
(Volt, Ohm) => Ampere,
(Ampere, Volt)
| (Ampere, Ohm)
| (Ohm, Volt)
| (Ohm, Ampere)
| (Watt, Ohm)
| (_, Watt) => {
panic!("Unavailable unit")
}
}
}
}