Getting data from a fmt::Arguments without heap allocation

499 Views Asked by At

I want to make write! work on my own struct implementing fmt::Write, and I don't have any heap allocation. To do so, I'd need to implement fmt::Write::write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result

However, this means that I need to access the data in a fmt::Arguments<'_> without using &args.to_string(), as .to_string() does not exist without heap allocation.

There is Arguments::as_str, however it doesn't work as soon as I need to format elements as i32.

Is there a way to get the arguments' strings without using .to_string() ?

1

There are 1 best solutions below

1
On BEST ANSWER

An Arguments<'_> contains a pre-parsed argument string and the arguments passed with it. You cannot break it up or mess around with the internals because that would be unsafe, so the only reasonable things you can do with it are:

  • pass it to core::fmt::write (or std::fmt::format, but that returns a String)
  • or pass it to one of the formatting macros (e.g. write!) along with a "{}" or "{:?}" format string.

The second option doesn't work in your case because you're implementing write_fmt, and write! calls write_fmt, so this would likely lead to infinite recursion. But you can still just call write(&mut self, args). write's implementation only uses write_str, not write_fmt.

In fact, the provided implementation of Write::write_fmt does exactly this:

fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> Result {
    write(&mut self, args)
}

Since this already exists, and there's no reasonable alternative implementation, you probably should not override write_fmt at all unless you have very specific requirements.