summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2021-12-07 13:44:43 -0500
committerJesse Luehrs <doy@tozt.net>2021-12-07 13:44:43 -0500
commit08246280e5707cc6a3153efc9648e33d2e122054 (patch)
treed9bc45daedc70357417bb1d81a48aaf436176155 /src
parent932a16d8fe617821a40332ec32ed9d5f682ca0dc (diff)
downloadnbsh-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.rs6
-rw-r--r--src/history.rs15
-rw-r--r--src/main.rs24
-rw-r--r--src/readline.rs5
-rw-r--r--src/state.rs21
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);
}
}