crud_pretty_struct/
formatters.rs

1use miette::Result;
2use owo_colors::OwoColorize;
3
4pub fn identity_formatter(x: &dyn ToString, _: bool) -> Result<(String, bool)> {
5  Ok((x.to_string(), false))
6}
7
8pub fn bool_check_formatter(b: &dyn ToString, colored: bool) -> Result<(String, bool)> {
9  Ok((
10    match (b.to_string().as_str(), colored) {
11      ("true", true) => "✔".green().to_string(),
12      ("true", false) => "✔".to_string(),
13      (_, true) => "✘".red().to_string(),
14      (_, false) => "✘".to_string(),
15    },
16    colored,
17  ))
18}
19
20// pub fn suffix_formatter(suffix: String) -> Box<Formatter> {
21//   Box::new(move |x: &dyn ToString, _: bool| -> Result<(String, bool)> {
22//     Ok((format!("{}{suffix}", x.to_string()), false))
23//   })
24// }
25
26#[cfg(feature = "chrono")]
27pub fn timestamp_formatter(value: &dyn ToString, _: bool) -> Result<(String, bool)> {
28  use chrono::{FixedOffset, NaiveDateTime};
29  use miette::{miette, Context, IntoDiagnostic};
30  let d = NaiveDateTime::parse_from_str(value.to_string().as_str(), "%s")
31    .into_diagnostic()
32    .with_context(|| format!("Can't parse timestamps: {}", value.to_string()))?
33    .and_local_timezone(FixedOffset::east_opt(0).ok_or(miette!("Can't create timezone"))?)
34    .unwrap();
35  Ok((d.to_string(), false))
36}
37
38#[cfg(feature = "humantime")]
39pub fn duration_formatter(value: &dyn ToString, _: bool) -> Result<(String, bool)> {
40  use humantime::format_duration;
41  use miette::{Context, IntoDiagnostic};
42  use std::time::Duration;
43
44  let d = Duration::from_secs_f64(
45    value
46      .to_string()
47      .parse::<f64>()
48      .into_diagnostic()
49      .with_context(|| format!("Can't parse duration: {}", value.to_string()))?
50      .abs(),
51  );
52  Ok((format_duration(d).to_string(), false))
53}
54
55#[cfg(feature = "markdown")]
56pub fn markdown_formatter(value: &dyn ToString, _: bool) -> Result<(String, bool)> {
57  Ok((termimad::term_text(&value.to_string()).to_string(), true))
58}
59
60#[cfg(feature = "bytesize")]
61pub fn byte_formatter(value: &dyn ToString, _: bool) -> Result<(String, bool)> {
62  use bytesize::ByteSize;
63  use miette::{Context, IntoDiagnostic};
64
65  let d = ByteSize(
66    value
67      .to_string()
68      .parse::<u64>()
69      .into_diagnostic()
70      .with_context(|| format!("Can't parse bytes: {}", value.to_string()))?,
71  );
72  Ok((d.to_string(), false))
73}
74
75#[cfg(test)]
76mod tests {
77  #[test]
78  #[cfg(feature = "humantime")]
79  fn duration_formatter_u64() {
80    use crate::formatters::duration_formatter;
81    assert_eq!(
82      duration_formatter(&"14", false).unwrap(),
83      ("14s".to_string(), false)
84    );
85  }
86
87  #[test]
88  #[cfg(feature = "humantime")]
89  fn duration_formatter_f64() {
90    use crate::formatters::duration_formatter;
91    assert_eq!(
92      duration_formatter(&"784.15", false).unwrap(),
93      ("13m 4s 150ms".to_string(), false)
94    );
95  }
96
97  #[test]
98  #[cfg(feature = "humantime")]
99  fn duration_formatter_f64_negative() {
100    use crate::formatters::duration_formatter;
101    assert_eq!(
102      duration_formatter(&"-784.15", false).unwrap(),
103      ("13m 4s 150ms".to_string(), false)
104    );
105  }
106
107  // #[test]
108  // #[cfg(feature = "humantime")]
109  // fn duration_formatter_err() {
110  //   use crate::formatters::duration_formatter;
111  //   assert_eq!(duration_formatter(&"x7", false), miette::Result::Err(()));
112  // }
113}