i3status_rs/formatting/
unit.rs1use std::fmt;
2use std::str::FromStr;
3
4use super::prefix::Prefix;
5use crate::errors::*;
6use crate::util::{celsius_to_fahrenheit, fahrenheit_to_celsius};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Unit {
10 Bytes,
12 Bits,
14 Percents,
16 #[deprecated = "Use DegreesC or DegreesF instead"]
18 DegreesUnspecified,
19 DegreesC,
21 DegreesF,
23 Seconds,
25 Watts,
27 Hertz,
29 None,
31}
32
33impl fmt::Display for Unit {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 f.write_str(match self {
36 Self::Bytes => "B",
37 Self::Bits => "b",
38 Self::Percents => "%",
39 #[expect(deprecated)]
40 Self::DegreesUnspecified | Self::DegreesC | Self::DegreesF => "°",
41 Self::Seconds => "s",
42 Self::Watts => "W",
43 Self::Hertz => "Hz",
44 Self::None => "",
45 })
46 }
47}
48
49impl FromStr for Unit {
50 type Err = Error;
51
52 fn from_str(s: &str) -> Result<Self> {
53 match s {
54 "B" => Ok(Unit::Bytes),
55 "b" => Ok(Unit::Bits),
56 "%" => Ok(Unit::Percents),
57 #[expect(deprecated)]
58 "deg" => Ok(Unit::DegreesUnspecified),
59 "degC" => Ok(Unit::DegreesC),
60 "degF" => Ok(Unit::DegreesF),
61 "s" => Ok(Unit::Seconds),
62 "W" => Ok(Unit::Watts),
63 "Hz" => Ok(Unit::Hertz),
64 "" => Ok(Unit::None),
65 x => Err(Error::new(format!("Unknown unit: '{x}'"))),
66 }
67 }
68}
69
70impl Unit {
71 pub fn convert(self, value: f64, unit: Self) -> Result<f64> {
72 match (self, unit) {
73 (x, y) if x == y => Ok(value),
74 (Self::Bytes, Self::Bits) => Ok(value * 8.),
75 (Self::Bits, Self::Bytes) => Ok(value / 8.),
76 #[expect(deprecated)]
77 (Self::DegreesC, Self::DegreesUnspecified)
78 | (Self::DegreesF, Self::DegreesUnspecified) => Ok(value),
79 (Self::DegreesC, Self::DegreesF) => Ok(celsius_to_fahrenheit(value)),
80 (Self::DegreesF, Self::DegreesC) => Ok(fahrenheit_to_celsius(value)),
81 _ => Err(Error::new(format!("Failed to convert '{self}' to '{unit}"))),
82 }
83 }
84
85 pub fn clamp_prefix(self, prefix: Prefix) -> Prefix {
86 match self {
87 Self::Bytes | Self::Bits => prefix.max(Prefix::One),
88 #[expect(deprecated)]
89 Self::Percents
90 | Self::DegreesUnspecified
91 | Self::DegreesC
92 | Self::DegreesF
93 | Self::None => Prefix::One,
94 _ => prefix,
95 }
96 }
97}