Equivalent of writeln! for tokio?

I'm porting some synchronous code to tokio, and I'm not sure how to port writeln!.

I have this:

    fn main() -> std::io::Result<()> {
        use std::{fs, io, io::Write};
        let mut f = io::BufWriter::new(fs::File::create("hello.txt")?);
        writeln!(f, "Hello world")?;
        Ok(())
    }

which works OK. In my tokio port, I have this:

    #[tokio::main]
    async fn main() -> tokio::io::Result<()> {
        use tokio::{fs, io};
        let mut f = io::BufWriter::new(fs::File::create("hello.txt").await?);
        // WHAT GOES HERE? writeln!(f, "Hello world")?;
        Ok(()) 
    }

writeln! doesn't work, since it expects the core::fmt::Write trait, which tokio's BufWriter doesn't implement (I think that's the problem, anyway).

Any guidance much appreciated!

1 Like

Currently you have to first write to a Vec<u8>, then write that.

let mut buf = Vec::<u8>::new();
writeln!(buf, "Hello world")?;
f.write_all(&buf).await?;
2 Likes

I suspected that might be the case.
Thanks!

Note that this arguably removes the need for you to use a BufWriter since you're already manually buffering with a vector. (or not, depends on how you use it)

1 Like

For those finding this thread, I came up with this macro that encapsulates Alice's pattern:

// Example usage:
//      use tokio::fs;
//      let mut f = fs::File::create("hello.txt").await?;
//      async_writeln!(f, "x  = {}", 123)?;
macro_rules! async_writeln {
    ($dst: expr) => {
        {
            tokio::io::AsyncWriteExt::write_all(&mut $dst, b"\n").await
        }
    };
    ($dst: expr, $fmt: expr) => {
        {
            use std::io::Write;
            let mut buf = Vec::<u8>::new();
            writeln!(buf, $fmt)?;
            tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
        }
    };
    ($dst: expr, $fmt: expr, $($arg: tt)*) => {
        {
            use std::io::Write;
            let mut buf = Vec::<u8>::new();
            writeln!(buf, $fmt, $( $arg )*)?;
            tokio::io::AsyncWriteExt::write_all(&mut $dst, &buf).await
        }
    };
}

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.