i3status_rs/formatting/formatter/
bar.rs1use super::*;
2
3const DEFAULT_BAR_VERTICAL: bool = false;
4const DEFAULT_BAR_WIDTH_HORIZONTAL: usize = 5;
5const DEFAULT_BAR_WIDTH_VERTICAL: usize = 1;
6const DEFAULT_BAR_MAX_VAL: f64 = 100.0;
7
8#[derive(Debug)]
9pub struct BarFormatter {
10 width: usize,
11 max_value: f64,
12 vertical: bool,
13}
14
15impl BarFormatter {
16 pub(super) fn from_args(args: &[Arg]) -> Result<Self> {
17 let mut vertical = DEFAULT_BAR_VERTICAL;
18 let mut width = None;
19 let mut max_value = DEFAULT_BAR_MAX_VAL;
20 for arg in args {
21 match arg.key {
22 "width" | "w" => {
23 width = Some(arg.parse_value()?);
24 }
25 "max_value" => {
26 max_value = arg.parse_value()?;
27 }
28 "vertical" | "v" => {
29 vertical = arg.parse_value()?;
30 }
31 other => {
32 return Err(Error::new(format!("Unknown argument for 'bar': '{other}'")));
33 }
34 }
35 }
36 Ok(Self {
37 width: width.unwrap_or(match vertical {
38 false => DEFAULT_BAR_WIDTH_HORIZONTAL,
39 true => DEFAULT_BAR_WIDTH_VERTICAL,
40 }),
41 max_value,
42 vertical,
43 })
44 }
45}
46
47const HORIZONTAL_BAR_CHARS: [char; 9] = [
48 ' ', '\u{258f}', '\u{258e}', '\u{258d}', '\u{258c}', '\u{258b}', '\u{258a}', '\u{2589}',
49 '\u{2588}',
50];
51
52const VERTICAL_BAR_CHARS: [char; 9] = [
53 ' ', '\u{2581}', '\u{2582}', '\u{2583}', '\u{2584}', '\u{2585}', '\u{2586}', '\u{2587}',
54 '\u{2588}',
55];
56
57impl Formatter for BarFormatter {
58 fn format(&self, val: &Value, _config: &SharedConfig) -> Result<String, FormatError> {
59 match val {
60 &Value::Number { mut val, .. } => {
61 val = (val / self.max_value).clamp(0., 1.);
62 if self.vertical {
63 let vert_char = VERTICAL_BAR_CHARS[(val * 8.) as usize];
64 Ok((0..self.width).map(|_| vert_char).collect())
65 } else {
66 let chars_to_fill = val * self.width as f64;
67 Ok((0..self.width)
68 .map(|i| {
69 HORIZONTAL_BAR_CHARS
70 [((chars_to_fill - i as f64).clamp(0., 1.) * 8.) as usize]
71 })
72 .collect())
73 }
74 }
75 other => Err(FormatError::IncompatibleFormatter {
76 ty: other.type_name(),
77 fmt: "bar",
78 }),
79 }
80 }
81}