diff --git a/src/main.rs b/src/main.rs index 6d9348d..79958f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,24 @@ use chrono::prelude::*; -use std::io::{stdin, stdout, ErrorKind, Read, StdoutLock, Write}; +use std::{ + env::args, + fs::File, + io::{stdin, stdout, Error as IoError, Read, StdoutLock, Write}, +}; + +type LogtimesResult = Result<(), IoError>; #[inline(always)] -fn print_time(output: &mut StdoutLock) -> Result<(), std::io::Error> { +fn print_time(output: &mut T) -> LogtimesResult +where + T: Write, +{ + let date_now = Local::now().format("%H:%M:%S%.9f"); + + write!(output, "[{}] ", &date_now) +} + +#[inline(always)] +fn print_time_color(output: &mut StdoutLock) -> Result<(), std::io::Error> { let date_now = Local::now().format("%H:%M:%S%.9f"); let color_green = "\x1b\x5b\x30\x3b\x33\x32\x6d"; @@ -12,13 +28,15 @@ fn print_time(output: &mut StdoutLock) -> Result<(), std::io::Error> { } #[inline(always)] -fn print_delete_line(output: &mut StdoutLock) -> Result<(), std::io::Error> { +fn print_delete_line(output: &mut StdoutLock) -> LogtimesResult { // tput dl1 und tput hpa 0 let bytes = "\x1b\x5b\x4d\x1b\x5b\x31\x47"; write!(output, "{}", bytes) } -fn run() -> Result<(), std::io::Error> { +fn run() -> LogtimesResult { + let mut log_file = args().nth(1).map(|f| File::create(f).unwrap()); + let out = stdout(); let mut output = out.lock(); @@ -30,24 +48,28 @@ fn run() -> Result<(), std::io::Error> { let mut linebuf = Vec::with_capacity(64 * 1024); loop { - if let Err(e) = input.read_exact(&mut buf) { - if e.kind() == ErrorKind::UnexpectedEof { - return Err(e); - } else { - output.flush()?; - return Ok(()); - } - } + // read 1 char + input.read_exact(&mut buf)?; + // push that char to the "current line" buffer linebuf.push(buf[0]); + // we encounter a newline -> delete the line and write it new as: + // [timestamp] actual content\n + // also write the line to the log file if there is one if buf[0] == 0xa { print_delete_line(&mut output)?; - print_time(&mut output)?; + print_time_color(&mut output)?; output.write_all(&linebuf)?; - output.flush()?; + if let Some(ref mut f) = log_file { + print_time(f)?; + f.write_all(&linebuf)?; + f.flush()?; + }; + + // clear line buffer so it is fresh for the next line linebuf.clear(); continue; }