Skip to content

Add fmt::Write to io::Write adapter #133

Open
@SUPERCILEX

Description

@SUPERCILEX

Proposal

Problem statement

There is no easy way to use fmt::Write to write bytes to an io stream.

Motivation, use-cases

If you know the format data you'll be creating must always be valid utf8, then you should use the fmt::Write trait. Unfortunately, it is harder than necessary to then lower that data down into a byte stream.

This basically comes down to being able to interchangeably use a String buffer or a io::stdout() buffer (for example). You could argue that you should use a Vec<u8> and then convert it to a string, but now you've lost the type safety of guaranteed utf8.

Solution sketches

rust-lang/rust#104389

The big open question is error handling, but I don't believe this needs to be addressed while the feature is unstable.

API:

struct FmtWriteAdapter<'a, W: Write + ?Sized> { ... }

impl FmtWriteAdapter {
    pub fn err(&self) -> &Option<Error>
    pub fn mut_err(&mut self) -> &mut Option<Error>
}

impl<W: Write + ?Sized> fmt::Write for FmtWriteAdapter<'_, W>

impl io::Write {
  fn fmt_adapter(&mut self) -> FmtWriteAdapter<'_, Self> where Self: Sized
}

Usage:

let mut output1 = String::new();
let mut output2 = io::stdout();

my_common_writer(&mut output1).unwrap();
my_common_writer(&mut output2.fmt_adapter()).unwrap();

fn my_common_writer(output: &mut impl fmt::Write) -> fmt::Result {
    writeln!(output, "Hello World!")
}

Links and related work

Existing issue: rust-lang/rust#77733

Note: the other direction (i.e. writing through an io stream to a format stream) does not make sense because the data does not have to be utf8. Even it was and error handling could be taken care of, the window of data the io stream is currently viewing may not be aligned to valid utf8 data, meaning the data may actually be utf8 but the order in which the writes appeared made the data invalid.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions