authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-15 22:11:03-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-15 22:11:03-04:00
log492a214d4c4f4feb15620dfd05230de0086825e5
treed0c98e07ff7a3f89738860f595af879779a3e62b
parent3625df25d6fe0b11e4c1c33454b621ec8a8c10ba

std.fmt.format: support {B} for human readable bytes


1 files changed, 55 insertions(+), 0 deletions(-)

std/fmt/index.zig+55
...@@ -27,6 +27,8 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -27,6 +27,8 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
27 Character,27 Character,
28 Buf,28 Buf,
29 BufWidth,29 BufWidth,
30 Bytes,
31 BytesWidth,
30 };32 };
3133
32 comptime var start_index = 0;34 comptime var start_index = 0;
...@@ -95,6 +97,10 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -95,6 +97,10 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
95 '.' => {97 '.' => {
96 state = State.Float;98 state = State.Float;
97 },99 },
100 'B' => {
101 width = 0;
102 state = State.Bytes;
103 },
98 else => @compileError("Unknown format character: " ++ []u8{c}),104 else => @compileError("Unknown format character: " ++ []u8{c}),
99 },105 },
100 State.Buf => switch (c) {106 State.Buf => switch (c) {
...@@ -206,6 +212,30 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),...@@ -206,6 +212,30 @@ pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context),
206 },212 },
207 else => @compileError("Unexpected character in format string: " ++ []u8{c}),213 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
208 },214 },
215 State.Bytes => switch (c) {
216 '}' => {
217 try formatBytes(args[next_arg], 0, context, Errors, output);
218 next_arg += 1;
219 state = State.Start;
220 start_index = i + 1;
221 },
222 '0' ... '9' => {
223 width_start = i;
224 state = State.BytesWidth;
225 },
226 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
227 },
228 State.BytesWidth => switch (c) {
229 '}' => {
230 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
231 try formatBytes(args[next_arg], width, context, Errors, output);
232 next_arg += 1;
233 state = State.Start;
234 start_index = i + 1;
235 },
236 '0' ... '9' => {},
237 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
238 },
209 }239 }
210 }240 }
211 comptime {241 comptime {
...@@ -520,6 +550,25 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com...@@ -520,6 +550,25 @@ pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, com
520 }550 }
521}551}
522552
553pub fn formatBytes(value: var, width: ?usize,
554 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
555{
556 if (value == 0) {
557 return output(context, "0B");
558 }
559
560 const mags = " KMGTPEZY";
561 const magnitude = math.min(math.log2(value) / 10, mags.len - 1);
562 const new_value = f64(value) / math.pow(f64, 1024, f64(magnitude));
563 const suffix = mags[magnitude];
564
565 try formatFloatDecimal(new_value, width, context, Errors, output);
566
567 if (suffix != ' ') {
568 try output(context, (&suffix)[0..1]);
569 }
570 return output(context, "B");
571}
523572
524pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,573pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
525 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void574 context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
...@@ -767,6 +816,12 @@ test "fmt.format" {...@@ -767,6 +816,12 @@ test "fmt.format" {
767 const result = try bufPrint(buf1[0..], "u3: {}\n", value);816 const result = try bufPrint(buf1[0..], "u3: {}\n", value);
768 assert(mem.eql(u8, result, "u3: 5\n"));817 assert(mem.eql(u8, result, "u3: 5\n"));
769 }818 }
819 {
820 var buf1: [32]u8 = undefined;
821 const value: usize = 63 * 1024 * 1024;
822 const result = try bufPrint(buf1[0..], "file size: {B}\n", value);
823 assert(mem.eql(u8, result, "file size: 63MB\n"));
824 }
770 {825 {
771 // Dummy field because of https://github.com/zig-lang/zig/issues/557.826 // Dummy field because of https://github.com/zig-lang/zig/issues/557.
772 const Struct = struct {827 const Struct = struct {