diff options
author | Jesse Luehrs <doy@tozt.net> | 2021-12-07 13:44:43 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2021-12-07 13:44:43 -0500 |
commit | 08246280e5707cc6a3153efc9648e33d2e122054 (patch) | |
tree | d9bc45daedc70357417bb1d81a48aaf436176155 /src | |
parent | 932a16d8fe617821a40332ec32ed9d5f682ca0dc (diff) | |
download | nbsh-08246280e5707cc6a3153efc9648e33d2e122054.tar.gz nbsh-08246280e5707cc6a3153efc9648e33d2e122054.zip |
move from chrono to time
chrono seems a bit unmaintained, and has a more awkward api
Diffstat (limited to 'src')
-rw-r--r-- | src/format.rs | 6 | ||||
-rw-r--r-- | src/history.rs | 15 | ||||
-rw-r--r-- | src/main.rs | 24 | ||||
-rw-r--r-- | src/readline.rs | 5 | ||||
-rw-r--r-- | src/state.rs | 21 |
5 files changed, 57 insertions, 14 deletions
diff --git a/src/format.rs b/src/format.rs index 50424f0..9086500 100644 --- a/src/format.rs +++ b/src/format.rs @@ -12,6 +12,12 @@ pub fn exit_status(status: std::process::ExitStatus) -> String { } } +pub fn time(time: time::OffsetDateTime) -> String { + let format = + time::format_description::parse("[hour]:[minute]:[second]").unwrap(); + time.format(&format).unwrap() +} + pub fn duration(dur: std::time::Duration) -> String { let secs = dur.as_secs(); let nanos = dur.subsec_nanos(); diff --git a/src/history.rs b/src/history.rs index 34093c3..bf09856 100644 --- a/src/history.rs +++ b/src/history.rs @@ -29,6 +29,7 @@ impl History { out: &mut textmode::Output, repl_lines: usize, focus: Option<usize>, + offset: time::UtcOffset, ) -> anyhow::Result<()> { let mut used_lines = repl_lines; let mut pos = None; @@ -47,7 +48,7 @@ impl History { (self.size.0 as usize - used_lines).try_into().unwrap(), 0, ); - entry.render(out, self.size.1, focused); + entry.render(out, self.size.1, focused, offset); if focused { pos = Some(out.screen().cursor_position()); } @@ -141,7 +142,7 @@ struct HistoryEntry { fullscreen: Option<bool>, input: async_std::channel::Sender<Vec<u8>>, resize: async_std::channel::Sender<(u16, u16)>, - start_time: chrono::DateTime<chrono::Local>, + start_time: time::OffsetDateTime, start_instant: std::time::Instant, exit_info: Option<ExitInfo>, } @@ -161,7 +162,7 @@ impl HistoryEntry { input, resize, fullscreen: None, - start_time: chrono::Local::now(), + start_time: time::OffsetDateTime::now_utc(), start_instant: std::time::Instant::now(), exit_info: None, } @@ -172,6 +173,7 @@ impl HistoryEntry { out: &mut textmode::Output, width: u16, focused: bool, + offset: time::UtcOffset, ) { out.set_bgcolor(textmode::Color::Rgb(32, 32, 32)); if let Some(info) = self.exit_info { @@ -205,11 +207,14 @@ impl HistoryEntry { let time = if let Some(info) = self.exit_info { format!( "[{} ({:6})]", - self.start_time.time().format("%H:%M:%S"), + crate::format::time(self.start_time.to_offset(offset)), crate::format::duration(info.instant - self.start_instant) ) } else { - format!("[{}]", self.start_time.time().format("%H:%M:%S")) + format!( + "[{}]", + crate::format::time(self.start_time.to_offset(offset)) + ) }; let cur_pos = out.screen().cursor_position(); out.write_str( diff --git a/src/main.rs b/src/main.rs index 2f850e8..0220ab9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,26 @@ mod util; use async_std::stream::StreamExt as _; +// the time crate is currently unable to get the local offset on unix due to +// soundness concerns, so we have to do it manually/: +// +// https://github.com/time-rs/time/issues/380 +fn get_offset() -> time::UtcOffset { + let offset_str = + std::process::Command::new("date").args(&["+%:z"]).output(); + if let Ok(offset_str) = offset_str { + let offset_str = String::from_utf8(offset_str.stdout).unwrap(); + time::UtcOffset::parse( + offset_str.trim(), + &time::format_description::parse("[offset_hour]:[offset_minute]") + .unwrap(), + ) + .unwrap_or(time::UtcOffset::UTC) + } else { + time::UtcOffset::UTC + } +} + async fn resize( action_w: &async_std::channel::Sender<crate::action::Action>, ) { @@ -39,7 +59,7 @@ async fn async_main() -> anyhow::Result<()> { let (action_w, action_r) = async_std::channel::unbounded(); - let state = state::State::new(); + let state = state::State::new(get_offset()); state.render(&mut output, true).await.unwrap(); let state = util::mutex(state); @@ -77,7 +97,7 @@ async fn async_main() -> anyhow::Result<()> { let action_w = action_w.clone(); async_std::task::spawn(async move { let first_sleep = 1_000_000_000_u64.saturating_sub( - chrono::Local::now().timestamp_subsec_nanos().into(), + time::OffsetDateTime::now_utc().nanosecond().into(), ); async_std::task::sleep(std::time::Duration::from_nanos( first_sleep, diff --git a/src/readline.rs b/src/readline.rs index 8b3c847..aef817a 100644 --- a/src/readline.rs +++ b/src/readline.rs @@ -57,6 +57,7 @@ impl Readline { &self, out: &mut textmode::Output, focus: bool, + offset: time::UtcOffset, ) -> anyhow::Result<()> { let mut pwd = std::env::current_dir()?.display().to_string(); let home = std::env::var("HOME")?; @@ -74,7 +75,9 @@ impl Readline { } let id = format!("{}@{}", user, hostname); let idlen: u16 = id.len().try_into().unwrap(); - let time = chrono::Local::now().format("%H:%M:%S").to_string(); + let time = crate::format::time( + time::OffsetDateTime::now_utc().to_offset(offset), + ); let timelen: u16 = time.len().try_into().unwrap(); out.move_to(self.size.0 - 2, 0); diff --git a/src/state.rs b/src/state.rs index 155034e..a312d91 100644 --- a/src/state.rs +++ b/src/state.rs @@ -7,10 +7,11 @@ pub struct State { scene: Scene, escape: bool, hide_readline: bool, + offset: time::UtcOffset, } impl State { - pub fn new() -> Self { + pub fn new(offset: time::UtcOffset) -> Self { let readline = crate::readline::Readline::new(); let history = crate::history::History::new(); let focus = Focus::Readline; @@ -22,6 +23,7 @@ impl State { scene, escape: false, hide_readline: false, + offset, } } @@ -111,19 +113,26 @@ impl State { Scene::Readline => match self.focus { Focus::Readline => { self.history - .render(out, self.readline.lines(), None) + .render(out, self.readline.lines(), None, self.offset) .await?; - self.readline.render(out, true).await?; + self.readline.render(out, true, self.offset).await?; } Focus::History(idx) => { if self.hide_readline { - self.history.render(out, 0, Some(idx)).await?; + self.history + .render(out, 0, Some(idx), self.offset) + .await?; } else { self.history - .render(out, self.readline.lines(), Some(idx)) + .render( + out, + self.readline.lines(), + Some(idx), + self.offset, + ) .await?; let pos = out.screen().cursor_position(); - self.readline.render(out, false).await?; + self.readline.render(out, false, self.offset).await?; out.move_to(pos.0, pos.1); } } |