Browse Source

Add handler for ctrl-c

master
Schneider 5 years ago
parent
commit
bc96a6cac1
Signed by: schneider GPG Key ID: 3F50B02A50039F3B
  1. 23
      Cargo.lock
  2. 1
      Cargo.toml
  3. 19
      src/duration.rs
  4. 32
      src/lib.rs
  5. 34
      src/main.rs

23
Cargo.lock

@ -1,5 +1,10 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "arc-swap"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.6"
@ -28,6 +33,20 @@ name = "lazy_static"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "signal-hook"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "0.6.8"
@ -41,6 +60,7 @@ name = "stopwatch"
version = "0.1.0"
dependencies = [
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -57,10 +77,13 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b"
"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047"
"checksum signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f272d1b7586bec132ed427f532dd418d8beca1ca7f2caf7df35569b1415a4b4"
"checksum smallvec 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "88aea073965ab29f6edb5493faf96ad662fb18aa9eeb186a3b7057951605ed15"
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"

1
Cargo.toml

@ -11,3 +11,4 @@ keywords = ["stopwatch", "cli", "time"]
[dependencies]
crossbeam-channel = "0.3"
signal-hook = "0.1"

19
src/duration.rs

@ -0,0 +1,19 @@
use std::convert::From;
use std::{fmt, time};
#[derive(Debug)]
pub struct FmtDuration(time::Duration);
impl fmt::Display for FmtDuration {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let secs = self.0.as_secs();
let millis = self.0.subsec_millis();
write!(f, "{:02}:{:02}:{:03}", secs / 60, secs % 60, millis)
}
}
impl From<time::Duration> for FmtDuration {
fn from(dur: time::Duration) -> Self {
FmtDuration(dur)
}
}

32
src/lib.rs

@ -0,0 +1,32 @@
use crossbeam_channel::{bounded, Receiver};
use duration::*;
use signal_hook::iterator::Signals;
use signal_hook::SIGINT;
use std::io::{Result, StdoutLock, Write};
use std::thread;
pub mod duration;
pub fn signal_handler() -> Result<Receiver<()>> {
let (s, r) = bounded(1);
let signals = Signals::new(&[SIGINT])?;
thread::spawn(move || {
for _ in signals.forever() {
if s.send(()).is_err() {
break;
}
}
});
Ok(r)
}
/// Resets the current line on stdout
///
/// # Arguments
///
/// * w - A reference to the locked stdout handle
pub fn reset_line(w: &mut StdoutLock) -> Result<()> {
write!(w, "\r[2K")
}

34
src/main.rs

@ -2,30 +2,44 @@
use crossbeam_channel::tick;
use std::io::{stdout, Write};
use std::time::{Duration, Instant};
use std::time::Instant;
use stopwatch::duration::FmtDuration;
use stopwatch::*;
#[macro_use]
extern crate crossbeam_channel;
fn main() {
let out = stdout();
let mut out = out.lock();
// 30 fps should be enough
let step_duration = Duration::from_millis(1000 / 30);
let step_duration = std::time::Duration::from_millis(1000 / 30);
let start = Instant::now();
let ticker = tick(step_duration);
let signals = match signal_handler() {
Ok(r) => r,
Err(err) => {
println!("{}", err);
return;
}
};
let out = stdout();
let mut out = out.lock();
let mut elapsed = FmtDuration::from(start.elapsed());
loop {
select! {
recv(ticker) -> now => {
let elapsed = now.unwrap().duration_since(start);
let secs = elapsed.as_secs();
let millis = elapsed.subsec_millis();
write!(out, "\r[2K").unwrap();
write!(out, "{:02}:{:02}:{:03}", secs/60, secs % 60, millis).unwrap();
elapsed = FmtDuration::from(now.unwrap().duration_since(start));
reset_line(&mut out).unwrap();
write!(out, "{}",elapsed).unwrap();
out.flush().unwrap();
}
recv(signals) -> _ => {
reset_line(&mut out).unwrap();
writeln!(out, "Total time: {}", elapsed).unwrap();
return;
}
}
}
}
Loading…
Cancel
Save