i3status_rs/formatting/
value.rs1use 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
56impl 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
134impl 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}