See title. What considerations should be kept in mind when deciding between these two methods of formatting data?
I’m working on hobby project to simplify using ANSI escape sequences for fancy terminal output. Some ANSI sequences are just const values, but others are parameterized (e.g. RGB colors); for these, I have functions which use std.fmt.bufPrint() to properly format the ANSI sequences, which can then be printed to the terminal.
Example ANSI RGB transformation to get reddish foreground text:
rgb(200, 50, 78) -> "\x1b[38;2;200;50;78m"
To accomplish this, the caller must pass a buffer to use with std.fmt.bufPrint(), which in turn uses the buffer to print via a .fixed std.Io.Writer:
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 {
var w: Writer = .fixed(buf);
w.print(fmt, args) catch |err| switch (err) {
error.WriteFailed => return error.NoSpaceLeft,
};
return w.buffered();
}
From what I understand, this is the correct use case for bufPrint(), which seems like a convenience function when you already know the max buffer len and want to store the result outside of a Writer. However, I’m wondering if passing a Writer around would be preferable, more flexible, etc over passing a buffer. Here are some specifics I’d like clarified:
- Either way the caller can decide whether to use stack or heap (either heap-allocate the buffer or use
Writer.Allocating), but theWriterversion is more flexible if resizing is necessary? - Since
stdoutuses aWriter, would it make sense to cut out the middleman and just passstdout?
Any insight is appreciated!