Initial proof of concept
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
mod irradiance;
|
||||
mod resistance;
|
||||
mod temperature;
|
||||
mod voltage;
|
||||
mod volume;
|
||||
mod volume_rate;
|
||||
mod pressure;
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
pub use defmt_impl::*;
|
||||
|
||||
pub use irradiance::*;
|
||||
pub use resistance::*;
|
||||
pub use temperature::*;
|
||||
pub use voltage::*;
|
||||
pub use volume::*;
|
||||
pub use volume_rate::*;
|
||||
pub use pressure::*;
|
||||
|
||||
use core::fmt::Display;
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::{Add, Sub};
|
||||
use num_traits::{FromPrimitive, Num, NumCast};
|
||||
|
||||
const DECA: u8 = 10;
|
||||
const DECI: u8 = 10;
|
||||
const HECTO: u8 = 100;
|
||||
const CENTI: u8 = 100;
|
||||
const KILO: u16 = 1_000;
|
||||
const MILLI: u16 = 1_000;
|
||||
const MEGA: u32 = 1_000_000;
|
||||
const MICRO: u32 = 1_000_000;
|
||||
const GIGA: u32 = 1_000_000_000;
|
||||
const NANO: u32 = 1_000_000_000;
|
||||
|
||||
pub trait Quantity<V: Value>: Copy + PartialEq + PartialOrd + Add + Sub {
|
||||
fn value(self) -> V;
|
||||
|
||||
fn symbol() -> &'static str;
|
||||
|
||||
/// Returns a wrapper that implements [Display] and [defmt::Format] for [Quantity]s with core number values.
|
||||
///
|
||||
/// - `rounding` - Sets the number of decimal places to round to when formatting (currently ignored with defmt).
|
||||
#[inline(always)]
|
||||
fn fmt(self, rounding: Option<usize>) -> Fmt<V, Self> {
|
||||
Fmt::new(self, rounding)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Value: Num + Copy + PartialOrd + FromPrimitive + NumCast + Display {}
|
||||
impl<V> Value for V where V: Num + Copy + PartialOrd + FromPrimitive + NumCast + Display {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Fmt<V: Value, Q: Quantity<V>> {
|
||||
quantity: Q,
|
||||
rounding: Option<usize>,
|
||||
_phantom: PhantomData<V>,
|
||||
}
|
||||
|
||||
impl<V: Value, Q: Quantity<V>> Fmt<V, Q> {
|
||||
#[inline(always)]
|
||||
fn new(quantity: Q, rounding: Option<usize>) -> Self {
|
||||
Self {
|
||||
quantity,
|
||||
rounding,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Value, Q: Quantity<V>> Display for Fmt<V, Q> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self.rounding {
|
||||
Some(places) => {
|
||||
write!(f, "{:.prec$} {}", self.quantity.value(), Q::symbol(), prec = places)
|
||||
},
|
||||
None => write!(f, "{} {}", self.quantity.value(), Q::symbol()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
mod defmt_impl {
|
||||
use super::*;
|
||||
use defmt::{write, Format, Formatter};
|
||||
|
||||
impl<Q: Quantity<u8>> Format for Fmt<u8, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<u16>> Format for Fmt<u16, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<u32>> Format for Fmt<u32, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<u64>> Format for Fmt<u64, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<u128>> Format for Fmt<u128, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<usize>> Format for Fmt<usize, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<i8>> Format for Fmt<i8, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<i16>> Format for Fmt<i16, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<i32>> Format for Fmt<i32, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<i64>> Format for Fmt<i64, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<i128>> Format for Fmt<i128, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<isize>> Format for Fmt<isize, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<f32>> Format for Fmt<f32, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
|
||||
impl<Q: Quantity<f64>> Format for Fmt<f64, Q> {
|
||||
fn format(&self, fmt: Formatter) {
|
||||
write!(fmt, "{} {}", self.quantity.value(), Q::symbol());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user