More datetime changes

* Accept the format string as Into<String> rather than String to allow
  &str to be provided.
* set_colors accepts Into<Vec<TimeColor>> rather than &[TimeColor]. The
  function needs a Vec<TimeColor>. Previously it would unconditionally
  clone the slice into a Vec, now it can accept a Vec if the user provides
  one and avoid an allocation in those cases (while still cloning a slice
  if that's what the user provides).
* DateTime::colors was an Option<Vec<TimeColor>> it's now simply a
  Vec<TimeColor>. There was no difference in logic between a None and an
  empty Vec so the code could be simplified by removing the Option.
* No longer allocate a String when formatting the time.
* Collapse the logic setting color. Calculating whether to set a color
  and storing the result in Option<ColorRGB> only to then set data.color
  if the Option is Some, can be collapsed to simply set data.color if the
  configuration dictates.
This commit is contained in:
Glenn Griffin 2019-10-01 11:27:06 -07:00
parent faae3bebca
commit de6bef6e36
3 changed files with 29 additions and 30 deletions

View File

@ -25,8 +25,8 @@ fn main() {
// Realtime upload/download rate for a interface
bar.push(NetworkSpeedWidget::new(&opts.nic, 6));
let mut dt = DateTimeWidget::new("%m/%d %H:%M".to_string());
dt.set_colors(&vec![
let mut dt = DateTimeWidget::new("%m/%d %H:%M");
dt.set_colors(vec![
TimeColor {
start: NaiveTime::from_hms(19, 0, 0),
color: ColorRGB::yellow(),

View File

@ -25,8 +25,8 @@ fn main() {
// Realtime upload/download rate for a interface
bar.push(NetworkSpeedWidget::new(&opts.nic, 6));
let mut dt = DateTimeWidget::tz("%H:%M %Z".to_string(), chrono_tz::Europe::London);
dt.set_colors(&vec![
let mut dt = DateTimeWidget::tz("%H:%M %Z", chrono_tz::Europe::London);
dt.set_colors(vec![
TimeColor {
start: NaiveTime::from_hms(0, 0, 0),
color: ColorRGB::red(),
@ -46,8 +46,8 @@ fn main() {
]);
bar.push(dt);
let mut dt = DateTimeWidget::new("%m/%d %H:%M".to_string());
dt.set_colors(&vec![
let mut dt = DateTimeWidget::new("%m/%d %H:%M");
dt.set_colors(vec![
TimeColor {
start: NaiveTime::from_hms(0, 0, 0),
color: ColorRGB::red(),

View File

@ -1,5 +1,5 @@
use chrono::{offset::TimeZone, Local, NaiveTime, Utc};
use std::fmt::Display;
use chrono::{Local, Utc, NaiveTime, offset::TimeZone};
use i3monkit::Block;
use i3monkit::ColorRGB;
@ -11,7 +11,7 @@ pub struct DateTimeWidget<Tz> {
/// https://docs.rs/chrono/*/chrono/format/strftime/index.html for documentation.
fmt: String,
tz: Tz,
colors: Option<Vec<TimeColor>>,
colors: Vec<TimeColor>,
}
#[derive(Clone)]
@ -21,7 +21,7 @@ pub struct TimeColor {
}
impl DateTimeWidget<Local> {
pub fn new(fmt: String) -> Self {
pub fn new(fmt: impl Into<String>) -> Self {
DateTimeWidget::tz(fmt, Local)
}
}
@ -31,17 +31,20 @@ where
Tz: TimeZone,
Tz::Offset: Display,
{
pub fn tz(fmt: String, tz: Tz) -> Self {
pub fn tz(fmt: impl Into<String>, tz: Tz) -> Self {
DateTimeWidget {
fmt,
fmt: fmt.into(),
tz,
colors: None,
colors: Vec::new(),
}
}
pub fn set_colors(&mut self, colors: &[TimeColor]) {
let mut colors = colors.to_vec();
pub fn set_colors(&mut self, colors: impl Into<Vec<TimeColor>>) {
let mut colors = colors.into();
colors.sort_by(|l, r| l.start.cmp(&r.start));
self.colors = Some(colors);
self.colors = colors;
}
fn now(&self) -> chrono::DateTime<Tz> {
Utc::now().with_timezone(&self.tz)
}
}
@ -51,29 +54,25 @@ where
Tz::Offset: Display,
{
fn update(&mut self) -> Option<WidgetUpdate> {
let (time, time_string) = {
let now = Utc::now().with_timezone(&self.tz);
(now.time(), now.format(&self.fmt).to_string())
};
let color = if let Some(colors) = &self.colors {
colors
.iter()
.filter(|tc| tc.start < time)
.last()
.map(|tc| tc.color.clone())
} else {
None
};
let now = self.now();
let time_string = format!(
r#"<span size="x-large" weight="heavy">{}</span>"#,
time_string
now.format(&self.fmt)
);
let mut data = Block::new()
.append_full_text(&time_string)
.use_pango()
.clone();
if let Some(color) = color {
let time = now.time();
if let Some(color) = self
.colors
.iter()
.filter(|tc| tc.start < time)
.last()
.map(|tc| tc.color.clone())
{
data.color(color);
}
Some(WidgetUpdate {