Skip to content

Commit

Permalink
Use a BufWriter for output instead of creating an intermediary string
Browse files Browse the repository at this point in the history
This should decrease the number of copies.
  • Loading branch information
lpenz committed Jul 1, 2023
1 parent 8712cb4 commit a62a38f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
50 changes: 29 additions & 21 deletions src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use color_eyre::{eyre::eyre, Result};
use std::convert::TryFrom;
use std::process::ExitStatus;
use std::process::Stdio;
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader};
use tokio::io::{self, AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter};
use tokio::process::Command;
use tokio_process_stream as tps;
use tokio_stream::wrappers::LinesStream;
Expand All @@ -25,40 +25,48 @@ pub fn buildcmd(cli: &Cli) -> Command {
cmd
}

pub fn decorate(prefix: &str, date: bool, line: &str) -> String {
let mut string = String::new();
pub async fn decor_write<T>(
prefix: &str,
date: bool,
line: &str,
output: &mut io::BufWriter<T>,
) -> Result<()>
where
T: AsyncWriteExt + std::marker::Unpin,
{
if date {
let now = chrono::offset::Local::now();
string.push_str(&now.format("%Y-%m-%d %H:%M:%S%.6f ").to_string());
let date = now.format("%Y-%m-%d %H:%M:%S%.6f ").to_string();
output.write_all(date.as_bytes()).await?;
}
string.push_str(prefix);
string.push(' ');
string.push_str(line);
string.push('\n');
string
output.write_all(prefix.as_bytes()).await?;
output.write_all(&[b' ']).await?;
output.write_all(line.as_bytes()).await?;
output.write_all(&[b'\n']).await?;
Ok(())
}

pub async fn do_write<T>(mut fd: T, prefix: &str, date: bool, line: &str) -> Result<()>
where
T: AsyncWriteExt + std::marker::Unpin,
{
let string = decorate(prefix, date, line);
fd.write_all(string.as_bytes()).await.map_err(|e| eyre!(e))
pub async fn decor_str(prefix: &str, date: bool, line: &str) -> Result<String> {
let mut output = Vec::<u8>::new();
let mut o = io::BufWriter::new(&mut output);
decor_write(prefix, date, line, &mut o).await?;
o.flush().await?;
Ok(std::str::from_utf8(&output)?.to_owned())
}

#[tracing::instrument]
pub async fn run(cli: &Cli) -> Result<ExitStatus> {
let cmd = buildcmd(cli);
let mut stream = tps::ProcessStream::try_from(cmd)?;
let mut stdout = io::stdout();
let mut stderr = io::stderr();
let mut stdout = BufWriter::new(io::stdout());
let mut stderr = BufWriter::new(io::stderr());
while let Some(item) = stream.next().await {
match item {
tps::Item::Stdout(line) => {
do_write(&mut stdout, &cli.prefix, cli.date, &line).await?;
decor_write(&cli.prefix, cli.date, &line, &mut stdout).await?;
}
tps::Item::Stderr(line) => {
do_write(&mut stderr, &cli.prefix, cli.date, &line).await?;
decor_write(&cli.prefix, cli.date, &line, &mut stderr).await?;
}
tps::Item::Done(s) => {
return Ok(s?);
Expand All @@ -71,9 +79,9 @@ pub async fn run(cli: &Cli) -> Result<ExitStatus> {
#[tracing::instrument]
pub async fn pipe(cli: &Cli) -> Result<()> {
let mut stdin_lines = LinesStream::new(BufReader::new(io::stdin()).lines());
let mut stdout = io::stdout();
let mut stdout = BufWriter::new(io::stdout());
while let Some(line) = stdin_lines.next().await {
do_write(&mut stdout, &cli.prefix, cli.date, &line?).await?;
decor_write(&cli.prefix, cli.date, &line?, &mut stdout).await?;
}
Ok(())
}
12 changes: 9 additions & 3 deletions tests/stdecor_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
// This file is subject to the terms and conditions defined in
// file 'LICENSE', which is part of this source code package.

use color_eyre::Result;

use stdecor::*;

#[test]
fn test_decorate() {
assert_eq!(&runner::decorate("1234", false, "abcd"), "1234 abcd\n");
#[tokio::test]
async fn test_decorate() -> Result<()> {
assert_eq!(
&runner::decor_str("1234", false, "abcd").await?,
"1234 abcd\n"
);
Ok(())
}

0 comments on commit a62a38f

Please sign in to comment.