i3status_rs/formatting/
formatter.rs

1use unicode_segmentation::UnicodeSegmentation as _;
2
3use std::time::Duration;
4use std::{borrow::Cow, fmt::Debug};
5
6use super::FormatError;
7use super::parse::Arg;
8use super::value::ValueInner as Value;
9use crate::config::SharedConfig;
10use crate::errors::*;
11
12// A helper macro for testing formatters
13#[cfg(test)]
14#[macro_export]
15macro_rules! new_fmt {
16    ($name:ident) => {{
17        new_fmt!($name,)
18    }};
19    ($name:ident, $($key:ident : $value:tt),* $(,)?) => {
20        new_formatter(stringify!($name), &[
21            $( Arg { key: stringify!($key), val: Some(stringify!($value)) } ),*
22        ])
23    };
24}
25
26mod bar;
27pub use bar::BarFormatter;
28mod tally;
29pub use tally::TallyFormatter;
30mod datetime;
31pub use datetime::{DEFAULT_DATETIME_FORMATTER, DatetimeFormatter};
32mod duration;
33pub use duration::{DEFAULT_DURATION_FORMATTER, DurationFormatter};
34mod eng;
35pub use eng::{DEFAULT_NUMBER_FORMATTER, EngFormatter};
36mod flag;
37pub use flag::{DEFAULT_FLAG_FORMATTER, FlagFormatter};
38mod pango;
39pub use pango::PangoStrFormatter;
40mod str;
41pub use str::{DEFAULT_STRING_FORMATTER, StrFormatter};
42
43type PadWith = Cow<'static, str>;
44
45const DEFAULT_NUMBER_PAD_WITH: PadWith = Cow::Borrowed(" ");
46
47pub trait Formatter: Debug + Send + Sync {
48    fn format(&self, val: &Value, config: &SharedConfig) -> Result<String, FormatError>;
49
50    fn interval(&self) -> Option<Duration> {
51        None
52    }
53}
54
55pub fn new_formatter(name: &str, args: &[Arg]) -> Result<Box<dyn Formatter>> {
56    match name {
57        "bar" => Ok(Box::new(BarFormatter::from_args(args)?)),
58        "datetime" => Ok(Box::new(DatetimeFormatter::from_args(args)?)),
59        "dur" | "duration" => Ok(Box::new(DurationFormatter::from_args(args)?)),
60        "eng" => Ok(Box::new(EngFormatter::from_args(args)?)),
61        "pango-str" => Ok(Box::new(PangoStrFormatter::from_args(args)?)),
62        "str" => Ok(Box::new(StrFormatter::from_args(args)?)),
63        "tally" => Ok(Box::new(TallyFormatter::from_args(args)?)),
64        _ => Err(Error::new(format!("Unknown formatter: '{name}'"))),
65    }
66}