2

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() ?

Naeio
  • 1,112
  • 7
  • 21
  • Implementing the `write_fmt` method is not required, and the default implementation doesn't do any heap allocation AFAIK. – kmdreko Oct 07 '21 at 20:52

1 Answers1

4

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.

trent
  • 25,033
  • 7
  • 51
  • 90
  • Thanks. At first, I didn''t implement `write_fmt`, as I read it was given once we implemented `write_str`. However, this caused my code to crash, and by implementing `write_fmt` such that it does nothing, my code ran. I don't know why so I assumed it had something with heap allocation, but apparently not. With your code at least, I'll be able to debug, thanks ! – Naeio Oct 08 '21 at 06:13