i3status_rs/formatting/
value.rs

1use std::borrow::Cow;
2use std::time::Duration;
3
4use super::Metadata;
5use super::formatter;
6use super::unit::Unit;
7use chrono::{DateTime, Utc};
8use chrono_tz::Tz;
9
10#[derive(Debug, Clone)]
11pub struct Value {
12    pub inner: ValueInner,
13    pub metadata: Metadata,
14}
15
16#[derive(Debug, Clone)]
17pub enum ValueInner {
18    Text(String),
19    Icon(Cow<'static, str>, Option<f64>),
20    Number { val: f64, unit: Unit },
21    Datetime(DateTime<Utc>, Option<Tz>),
22    Duration(Duration),
23    Flag,
24}
25
26impl ValueInner {
27    pub fn type_name(&self) -> &'static str {
28        match self {
29            ValueInner::Text(..) => "Text",
30            ValueInner::Icon(..) => "Icon",
31            ValueInner::Number { .. } => "Number",
32            ValueInner::Datetime(..) => "Datetime",
33            ValueInner::Duration(..) => "Duration",
34            ValueInner::Flag => "Flag",
35        }
36    }
37}
38
39pub trait IntoF64 {
40    fn into_f64(self) -> f64;
41}
42
43macro_rules! impl_into_f64 {
44    ($($t:ty),+) => {
45        $(
46            impl IntoF64 for $t {
47                fn into_f64(self) -> f64 {
48                    self as _
49                }
50            }
51        )+
52    }
53}
54impl_into_f64!(f64, f32, i64, u64, i32, u32, i16, u16, i8, u8, usize, isize);
55
56/// Constructors
57impl Value {
58    pub fn new(val: ValueInner) -> Self {
59        Self {
60            inner: val,
61            metadata: Default::default(),
62        }
63    }
64
65    pub fn flag() -> Self {
66        Self::new(ValueInner::Flag)
67    }
68
69    pub fn datetime(datetime: DateTime<Utc>, tz: Option<Tz>) -> Self {
70        Self::new(ValueInner::Datetime(datetime, tz))
71    }
72
73    pub fn duration(duration: Duration) -> Self {
74        Self::new(ValueInner::Duration(duration))
75    }
76
77    pub fn icon<S>(name: S) -> Self
78    where
79        S: Into<Cow<'static, str>>,
80    {
81        Self::new(ValueInner::Icon(name.into(), None))
82    }
83
84    pub fn icon_progression<S>(name: S, value: f64) -> Self
85    where
86        S: Into<Cow<'static, str>>,
87    {
88        Self::new(ValueInner::Icon(name.into(), Some(value)))
89    }
90    pub fn icon_progression_bound<S>(name: S, value: f64, low: f64, high: f64) -> Self
91    where
92        S: Into<Cow<'static, str>>,
93    {
94        Self::icon_progression(name, (value.clamp(low, high) - low) / (high - low))
95    }
96
97    pub fn text(text: String) -> Self {
98        Self::new(ValueInner::Text(text))
99    }
100
101    pub fn number_unit(val: impl IntoF64, unit: Unit) -> Self {
102        Self::new(ValueInner::Number {
103            val: val.into_f64(),
104            unit,
105        })
106    }
107
108    pub fn bytes(val: impl IntoF64) -> Self {
109        Self::number_unit(val, Unit::Bytes)
110    }
111    pub fn bits(val: impl IntoF64) -> Self {
112        Self::number_unit(val, Unit::Bits)
113    }
114    pub fn percents(val: impl IntoF64) -> Self {
115        Self::number_unit(val, Unit::Percents)
116    }
117    pub fn degrees(val: impl IntoF64) -> Self {
118        Self::number_unit(val, Unit::Degrees)
119    }
120    pub fn seconds(val: impl IntoF64) -> Self {
121        Self::number_unit(val, Unit::Seconds)
122    }
123    pub fn watts(val: impl IntoF64) -> Self {
124        Self::number_unit(val, Unit::Watts)
125    }
126    pub fn hertz(val: impl IntoF64) -> Self {
127        Self::number_unit(val, Unit::Hertz)
128    }
129    pub fn number(val: impl IntoF64) -> Self {
130        Self::number_unit(val, Unit::None)
131    }
132}
133
134/// Set options
135impl Value {
136    pub fn with_instance(mut self, instance: &'static str) -> Self {
137        self.metadata.instance = Some(instance);
138        self
139    }
140
141    pub fn underline(mut self, val: bool) -> Self {
142        self.metadata.underline = val;
143        self
144    }
145
146    pub fn italic(mut self, val: bool) -> Self {
147        self.metadata.italic = val;
148        self
149    }
150
151    pub fn default_formatter(&self) -> &'static dyn formatter::Formatter {
152        match &self.inner {
153            ValueInner::Text(_) | ValueInner::Icon(..) => &formatter::DEFAULT_STRING_FORMATTER,
154            ValueInner::Number { .. } => &formatter::DEFAULT_NUMBER_FORMATTER,
155            ValueInner::Datetime { .. } => &*formatter::DEFAULT_DATETIME_FORMATTER,
156            ValueInner::Duration { .. } => &formatter::DEFAULT_DURATION_FORMATTER,
157            ValueInner::Flag => &formatter::DEFAULT_FLAG_FORMATTER,
158        }
159    }
160}