Skip to main content

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
91    pub fn icon_progression_bound<S>(name: S, value: f64, low: f64, high: f64) -> Self
92    where
93        S: Into<Cow<'static, str>>,
94    {
95        Self::icon_progression(name, (value.clamp(low, high) - low) / (high - low))
96    }
97
98    pub fn text(text: String) -> Self {
99        Self::new(ValueInner::Text(text))
100    }
101
102    pub fn number_unit(val: impl IntoF64, unit: Unit) -> Self {
103        Self::new(ValueInner::Number {
104            val: val.into_f64(),
105            unit,
106        })
107    }
108
109    pub fn bytes(val: impl IntoF64) -> Self {
110        Self::number_unit(val, Unit::Bytes)
111    }
112    pub fn bits(val: impl IntoF64) -> Self {
113        Self::number_unit(val, Unit::Bits)
114    }
115    pub fn percents(val: impl IntoF64) -> Self {
116        Self::number_unit(val, Unit::Percents)
117    }
118    pub fn degrees_c(val: impl IntoF64) -> Self {
119        Self::number_unit(val, Unit::DegreesC)
120    }
121    pub fn degrees_f(val: impl IntoF64) -> Self {
122        Self::number_unit(val, Unit::DegreesF)
123    }
124    pub fn seconds(val: impl IntoF64) -> Self {
125        Self::number_unit(val, Unit::Seconds)
126    }
127    pub fn watts(val: impl IntoF64) -> Self {
128        Self::number_unit(val, Unit::Watts)
129    }
130    pub fn hertz(val: impl IntoF64) -> Self {
131        Self::number_unit(val, Unit::Hertz)
132    }
133    pub fn number(val: impl IntoF64) -> Self {
134        Self::number_unit(val, Unit::None)
135    }
136}
137
138/// Set options
139impl Value {
140    pub fn with_instance(mut self, instance: &'static str) -> Self {
141        self.metadata.instance = Some(instance);
142        self
143    }
144
145    pub fn underline(mut self, val: bool) -> Self {
146        self.metadata.underline = val;
147        self
148    }
149
150    pub fn italic(mut self, val: bool) -> Self {
151        self.metadata.italic = val;
152        self
153    }
154
155    pub fn default_formatter(&self) -> &'static dyn formatter::Formatter {
156        match &self.inner {
157            ValueInner::Text(_) | ValueInner::Icon(..) => &formatter::DEFAULT_STRING_FORMATTER,
158            ValueInner::Number { .. } => &formatter::DEFAULT_NUMBER_FORMATTER,
159            ValueInner::Datetime { .. } => &*formatter::DEFAULT_DATETIME_FORMATTER,
160            ValueInner::Duration { .. } => &formatter::DEFAULT_DURATION_FORMATTER,
161            ValueInner::Flag => &formatter::DEFAULT_FLAG_FORMATTER,
162        }
163    }
164}