diff --git a/lib/std/buffer.zig b/lib/std/buffer.zig index 28ce2a561062f0a84f55c58c10c1c3b9d359a293..93281c35ec497509ab2850937bf6fb5b5111786a 100644 --- a/lib/std/buffer.zig +++ b/lib/std/buffer.zig @@ -65,15 +65,9 @@ pub const Buffer = struct { } pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer { - const countSize = struct { - fn countSize(size: *usize, bytes: []const u8) (error{}!void) { - size.* += bytes.len; - } - }.countSize; - var size: usize = 0; - std.fmt.format(&size, error{}, countSize, format, args) catch |err| switch (err) {}; + const size = std.fmtstream.count(format, args); var self = try Buffer.initSize(allocator, size); - assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size); + assert((std.fmtstream.bufPrint(self.list.items, format, args) catch unreachable).len == size); return self; } @@ -155,7 +149,7 @@ pub const Buffer = struct { } pub fn print(self: *Buffer, comptime fmt: []const u8, args: var) !void { - return std.fmt.format(self, error{OutOfMemory}, Buffer.append, fmt, args); + return self.outStream().print(fmt, args); } pub fn outStream(self: *Buffer) std.io.OutStream(*Buffer, error{OutOfMemory}, appendWrite) { diff --git a/lib/std/fmtstream.zig b/lib/std/fmtstream.zig index 8db0052a761c388bfb5aa669220590adc35cb2c4..237d0014501b46d3e09c33ae1cbad4ef92935309 100644 --- a/lib/std/fmtstream.zig +++ b/lib/std/fmtstream.zig @@ -1080,14 +1080,17 @@ pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: var) BufPrintError![] return buf[0..fbs.pos]; } -pub const AllocPrintError = error{OutOfMemory}; - -pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![]u8 { - // Count the characters we need to preallocate +// Count the characters needed for format. Useful for preallocating memory +pub fn count(comptime fmt: []const u8, args: var) usize { var counting_stream = std.io.countingOutStream(std.io.null_out_stream); format(counting_stream.outStream(), fmt, args) catch |err| switch (err) {}; + return counting_stream.bytes_written; +} - const buf = try allocator.alloc(u8, counting_stream.bytes_written); +pub const AllocPrintError = error{OutOfMemory}; + +pub fn allocPrint(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![]u8 { + const buf = try allocator.alloc(u8, count(fmt, args)); return bufPrint(buf, fmt, args) catch |err| switch (err) { error.BufferTooSmall => unreachable, // we just counted the size above };