i3status_rs/formatting/
unit.rs

1use std::fmt;
2use std::str::FromStr;
3
4use super::prefix::Prefix;
5use crate::errors::*;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Unit {
9    /// `B`
10    Bytes,
11    /// `b`
12    Bits,
13    /// `%`
14    Percents,
15    /// `deg`
16    Degrees,
17    /// `s`
18    Seconds,
19    /// `W`
20    Watts,
21    /// `Hz`
22    Hertz,
23    /// ``
24    None,
25}
26
27impl fmt::Display for Unit {
28    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29        f.write_str(match self {
30            Self::Bytes => "B",
31            Self::Bits => "b",
32            Self::Percents => "%",
33            Self::Degrees => "°",
34            Self::Seconds => "s",
35            Self::Watts => "W",
36            Self::Hertz => "Hz",
37            Self::None => "",
38        })
39    }
40}
41
42impl FromStr for Unit {
43    type Err = Error;
44
45    fn from_str(s: &str) -> Result<Self> {
46        match s {
47            "B" => Ok(Unit::Bytes),
48            "b" => Ok(Unit::Bits),
49            "%" => Ok(Unit::Percents),
50            "deg" => Ok(Unit::Degrees),
51            "s" => Ok(Unit::Seconds),
52            "W" => Ok(Unit::Watts),
53            "Hz" => Ok(Unit::Hertz),
54            "" => Ok(Unit::None),
55            x => Err(Error::new(format!("Unknown unit: '{x}'"))),
56        }
57    }
58}
59
60impl Unit {
61    pub fn convert(self, value: f64, unit: Self) -> Result<f64> {
62        match (self, unit) {
63            (x, y) if x == y => Ok(value),
64            (Self::Bytes, Self::Bits) => Ok(value * 8.),
65            (Self::Bits, Self::Bytes) => Ok(value / 8.),
66            _ => Err(Error::new(format!("Failed to convert '{self}' to '{unit}"))),
67        }
68    }
69
70    pub fn clamp_prefix(self, prefix: Prefix) -> Prefix {
71        match self {
72            Self::Bytes | Self::Bits => prefix.max(Prefix::One),
73            Self::Percents | Self::Degrees | Self::None => Prefix::One,
74            _ => prefix,
75        }
76    }
77}