| author | |
| committer | |
| log | 99229ceb55be717aa1995f1a0105bc6b96a910f6 |
| tree | fa3d122d0d429fd002e097d553de0c508267b764 |
| parent | 8c70fd0a57936cca236a000a17364cbbf7a09673 |
Remove the `{D}` format specifier. It is moved into `std.Io.Duration` as
a format method.
Migration plan:
```diff
-writer.print("{D}", .{ns});
+writer.print("{f}", .{std.Io.Duration{ .nanoseconds = ns }});
```
All instances where `{D}` was used have been changed to use
`std.Io.Duration` and `{f}`.
Fixes #312814 files changed, 166 insertions(+), 237 deletions(-)
lib/build-web/time_report.zig+39-39| ... | @@ -42,10 +42,10 @@ pub fn genericResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { | ... | @@ -42,10 +42,10 @@ pub fn genericResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { |
| 42 | if (msg.step_idx >= step_list.*.len) @panic("malformed GenericResult message"); | 42 | if (msg.step_idx >= step_list.*.len) @panic("malformed GenericResult message"); |
| 43 | const inner_html = try std.fmt.allocPrint(gpa, | 43 | const inner_html = try std.fmt.allocPrint(gpa, |
| 44 | \\<code slot="step-name">{[step_name]f}</code> | 44 | \\<code slot="step-name">{[step_name]f}</code> |
| 45 | \\<span slot="stat-total-time">{[stat_total_time]D}</span> | 45 | \\<span slot="stat-total-time">{[stat_total_time]f}</span> |
| 46 | , .{ | 46 | , .{ |
| 47 | .step_name = fmtEscapeHtml(step_list.*[msg.step_idx].name), | 47 | .step_name = fmtEscapeHtml(step_list.*[msg.step_idx].name), |
| 48 | .stat_total_time = msg.ns_total, | 48 | .stat_total_time = std.Io.Duration{ .nanoseconds = msg.ns_total }, |
| 49 | }); | 49 | }); |
| 50 | defer gpa.free(inner_html); | 50 | defer gpa.free(inner_html); |
| 51 | js.updateGeneric(msg.step_idx, inner_html.ptr, inner_html.len); | 51 | js.updateGeneric(msg.step_idx, inner_html.ptr, inner_html.len); |
| ... | @@ -139,16 +139,16 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -139,16 +139,16 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 139 | \\<span slot="stat-imported-files">{[stat_imported_files]d}</span> | 139 | \\<span slot="stat-imported-files">{[stat_imported_files]d}</span> |
| 140 | \\<span slot="stat-generic-instances">{[stat_generic_instances]d}</span> | 140 | \\<span slot="stat-generic-instances">{[stat_generic_instances]d}</span> |
| 141 | \\<span slot="stat-inline-calls">{[stat_inline_calls]d}</span> | 141 | \\<span slot="stat-inline-calls">{[stat_inline_calls]d}</span> |
| 142 | \\<span slot="stat-compilation-time">{[stat_compilation_time]D}</span> | 142 | \\<span slot="stat-compilation-time">{[stat_compilation_time]f}</span> |
| 143 | \\<span slot="cpu-time-parse">{[cpu_time_parse]D}</span> | 143 | \\<span slot="cpu-time-parse">{[cpu_time_parse]f}</span> |
| 144 | \\<span slot="cpu-time-astgen">{[cpu_time_astgen]D}</span> | 144 | \\<span slot="cpu-time-astgen">{[cpu_time_astgen]f}</span> |
| 145 | \\<span slot="cpu-time-sema">{[cpu_time_sema]D}</span> | 145 | \\<span slot="cpu-time-sema">{[cpu_time_sema]f}</span> |
| 146 | \\<span slot="cpu-time-codegen">{[cpu_time_codegen]D}</span> | 146 | \\<span slot="cpu-time-codegen">{[cpu_time_codegen]f}</span> |
| 147 | \\<span slot="cpu-time-link">{[cpu_time_link]D}</span> | 147 | \\<span slot="cpu-time-link">{[cpu_time_link]f}</span> |
| 148 | \\<span slot="real-time-files">{[real_time_files]D}</span> | 148 | \\<span slot="real-time-files">{[real_time_files]f}</span> |
| 149 | \\<span slot="real-time-decls">{[real_time_decls]D}</span> | 149 | \\<span slot="real-time-decls">{[real_time_decls]f}</span> |
| 150 | \\<span slot="real-time-llvm-emit">{[real_time_llvm_emit]D}</span> | 150 | \\<span slot="real-time-llvm-emit">{[real_time_llvm_emit]f}</span> |
| 151 | \\<span slot="real-time-link-flush">{[real_time_link_flush]D}</span> | 151 | \\<span slot="real-time-link-flush">{[real_time_link_flush]f}</span> |
| 152 | \\<pre slot="llvm-pass-timings"><code>{[llvm_pass_timings]f}</code></pre> | 152 | \\<pre slot="llvm-pass-timings"><code>{[llvm_pass_timings]f}</code></pre> |
| 153 | \\ | 153 | \\ |
| 154 | , .{ | 154 | , .{ |
| ... | @@ -157,17 +157,17 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -157,17 +157,17 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 157 | .stat_imported_files = stats.n_imported_files, | 157 | .stat_imported_files = stats.n_imported_files, |
| 158 | .stat_generic_instances = stats.n_generic_instances, | 158 | .stat_generic_instances = stats.n_generic_instances, |
| 159 | .stat_inline_calls = stats.n_inline_calls, | 159 | .stat_inline_calls = stats.n_inline_calls, |
| 160 | .stat_compilation_time = hdr.ns_total, | 160 | .stat_compilation_time = std.Io.Duration{ .nanoseconds = hdr.ns_total }, |
| 161 | 161 | ||
| 162 | .cpu_time_parse = stats.cpu_ns_parse, | 162 | .cpu_time_parse = std.Io.Duration{ .nanoseconds = stats.cpu_ns_parse }, |
| 163 | .cpu_time_astgen = stats.cpu_ns_astgen, | 163 | .cpu_time_astgen = std.Io.Duration{ .nanoseconds = stats.cpu_ns_astgen }, |
| 164 | .cpu_time_sema = stats.cpu_ns_sema, | 164 | .cpu_time_sema = std.Io.Duration{ .nanoseconds = stats.cpu_ns_sema }, |
| 165 | .cpu_time_codegen = stats.cpu_ns_codegen, | 165 | .cpu_time_codegen = std.Io.Duration{ .nanoseconds = stats.cpu_ns_codegen }, |
| 166 | .cpu_time_link = stats.cpu_ns_link, | 166 | .cpu_time_link = std.Io.Duration{ .nanoseconds = stats.cpu_ns_link }, |
| 167 | .real_time_files = stats.real_ns_files, | 167 | .real_time_files = std.Io.Duration{ .nanoseconds = stats.real_ns_files }, |
| 168 | .real_time_decls = stats.real_ns_decls, | 168 | .real_time_decls = std.Io.Duration{ .nanoseconds = stats.real_ns_decls }, |
| 169 | .real_time_llvm_emit = stats.real_ns_llvm_emit, | 169 | .real_time_llvm_emit = std.Io.Duration{ .nanoseconds = stats.real_ns_llvm_emit }, |
| 170 | .real_time_link_flush = stats.real_ns_link_flush, | 170 | .real_time_link_flush = std.Io.Duration{ .nanoseconds = stats.real_ns_link_flush }, |
| 171 | 171 | ||
| 172 | .llvm_pass_timings = fmtEscapeHtml(llvm_pass_timings), | 172 | .llvm_pass_timings = fmtEscapeHtml(llvm_pass_timings), |
| 173 | }); | 173 | }); |
| ... | @@ -180,18 +180,18 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -180,18 +180,18 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 180 | try file_table_html.writer.print( | 180 | try file_table_html.writer.print( |
| 181 | \\<tr> | 181 | \\<tr> |
| 182 | \\ <th scope="row"><code>{f}</code></th> | 182 | \\ <th scope="row"><code>{f}</code></th> |
| 183 | \\ <td>{D}</td> | 183 | \\ <td>{f}</td> |
| 184 | \\ <td>{D}</td> | 184 | \\ <td>{f}</td> |
| 185 | \\ <td>{D}</td> | 185 | \\ <td>{f}</td> |
| 186 | \\ <td>{D}</td> | 186 | \\ <td>{f}</td> |
| 187 | \\</tr> | 187 | \\</tr> |
| 188 | \\ | 188 | \\ |
| 189 | , .{ | 189 | , .{ |
| 190 | fmtEscapeHtml(file.name), | 190 | fmtEscapeHtml(file.name), |
| 191 | file.ns_sema, | 191 | std.Io.Duration{ .nanoseconds = file.ns_sema }, |
| 192 | file.ns_codegen, | 192 | std.Io.Duration{ .nanoseconds = file.ns_codegen }, |
| 193 | file.ns_link, | 193 | std.Io.Duration{ .nanoseconds = file.ns_link }, |
| 194 | file.ns_sema + file.ns_codegen + file.ns_link, | 194 | std.Io.Duration{ .nanoseconds = file.ns_sema + file.ns_codegen + file.ns_link }, |
| 195 | }); | 195 | }); |
| 196 | } | 196 | } |
| 197 | if (slowest_files.len > max_table_rows) { | 197 | if (slowest_files.len > max_table_rows) { |
| ... | @@ -210,20 +210,20 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v | ... | @@ -210,20 +210,20 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v |
| 210 | \\ <th scope="row"><code>{f}</code></th> | 210 | \\ <th scope="row"><code>{f}</code></th> |
| 211 | \\ <th scope="row"><code>{f}</code></th> | 211 | \\ <th scope="row"><code>{f}</code></th> |
| 212 | \\ <td>{d}</td> | 212 | \\ <td>{d}</td> |
| 213 | \\ <td>{D}</td> | 213 | \\ <td>{f}</td> |
| 214 | \\ <td>{D}</td> | 214 | \\ <td>{f}</td> |
| 215 | \\ <td>{D}</td> | 215 | \\ <td>{f}</td> |
| 216 | \\ <td>{D}</td> | 216 | \\ <td>{f}</td> |
| 217 | \\</tr> | 217 | \\</tr> |
| 218 | \\ | 218 | \\ |
| 219 | , .{ | 219 | , .{ |
| 220 | fmtEscapeHtml(decl.file_name), | 220 | fmtEscapeHtml(decl.file_name), |
| 221 | fmtEscapeHtml(decl.name), | 221 | fmtEscapeHtml(decl.name), |
| 222 | decl.sema_count, | 222 | decl.sema_count, |
| 223 | decl.ns_sema, | 223 | std.Io.Duration{ .nanoseconds = decl.ns_sema }, |
| 224 | decl.ns_codegen, | 224 | std.Io.Duration{ .nanoseconds = decl.ns_codegen }, |
| 225 | decl.ns_link, | 225 | std.Io.Duration{ .nanoseconds = decl.ns_link }, |
| 226 | decl.ns_sema + decl.ns_codegen + decl.ns_link, | 226 | std.Io.Duration{ .nanoseconds = decl.ns_sema + decl.ns_codegen + decl.ns_link }, |
| 227 | }); | 227 | }); |
| 228 | } | 228 | } |
| 229 | if (slowest_decls.len > max_table_rows) { | 229 | if (slowest_decls.len > max_table_rows) { |
| ... | @@ -265,7 +265,7 @@ pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { | ... | @@ -265,7 +265,7 @@ pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { |
| 265 | if (test_ns == std.math.maxInt(u64)) { | 265 | if (test_ns == std.math.maxInt(u64)) { |
| 266 | try table_html.appendSlice(gpa, "<td class=\"empty-cell\"></td>"); // didn't run | 266 | try table_html.appendSlice(gpa, "<td class=\"empty-cell\"></td>"); // didn't run |
| 267 | } else { | 267 | } else { |
| 268 | try table_html.print(gpa, "<td>{D}</td>", .{test_ns}); | 268 | try table_html.print(gpa, "<td>{f}</td>", .{std.Io.Duration{ .nanoseconds = test_ns }}); |
| 269 | } | 269 | } |
| 270 | try table_html.appendSlice(gpa, "</tr>\n"); | 270 | try table_html.appendSlice(gpa, "</tr>\n"); |
| 271 | } | 271 | } |
lib/std/Build/Step/Run.zig+3-3| ... | @@ -1787,9 +1787,9 @@ fn evalZigTest( | ... | @@ -1787,9 +1787,9 @@ fn evalZigTest( |
| 1787 | // the next test. | 1787 | // the next test. |
| 1788 | test_metadata.?.ns_per_test[test_index] = timeout.ns_elapsed; | 1788 | test_metadata.?.ns_per_test[test_index] = timeout.ns_elapsed; |
| 1789 | test_results.timeout_count += 1; | 1789 | test_results.timeout_count += 1; |
| 1790 | try run.step.addError("'{s}' timed out after {D}{s}{s}", .{ | 1790 | try run.step.addError("'{s}' timed out after {f}{s}{s}", .{ |
| 1791 | test_metadata.?.testName(test_index), | 1791 | test_metadata.?.testName(test_index), |
| 1792 | timeout.ns_elapsed, | 1792 | Io.Duration{ .nanoseconds = timeout.ns_elapsed }, |
| 1793 | if (stderr.len != 0) " with stderr:\n" else "", | 1793 | if (stderr.len != 0) " with stderr:\n" else "", |
| 1794 | std.mem.trim(u8, stderr, "\n"), | 1794 | std.mem.trim(u8, stderr, "\n"), |
| 1795 | }); | 1795 | }); |
| ... | @@ -1799,7 +1799,7 @@ fn evalZigTest( | ... | @@ -1799,7 +1799,7 @@ fn evalZigTest( |
| 1799 | run.step.result_stderr = try arena.dupe(u8, stderr); | 1799 | run.step.result_stderr = try arena.dupe(u8, stderr); |
| 1800 | // The individual unit test results in `results` are irrelevant: the test runner | 1800 | // The individual unit test results in `results` are irrelevant: the test runner |
| 1801 | // is broken! Fail immediately without populating `s.test_results`. | 1801 | // is broken! Fail immediately without populating `s.test_results`. |
| 1802 | return run.step.fail("test runner failed to respond for {D}", .{timeout.ns_elapsed}); | 1802 | return run.step.fail("test runner failed to respond for {f}", .{Io.Duration{ .nanoseconds = timeout.ns_elapsed }}); |
| 1803 | }, | 1803 | }, |
| 1804 | } | 1804 | } |
| 1805 | comptime unreachable; | 1805 | comptime unreachable; |
lib/std/Io.zig+124| ... | @@ -940,6 +940,130 @@ pub const Duration = struct { | ... | @@ -940,6 +940,130 @@ pub const Duration = struct { |
| 940 | pub fn toNanoseconds(d: Duration) i96 { | 940 | pub fn toNanoseconds(d: Duration) i96 { |
| 941 | return d.nanoseconds; | 941 | return d.nanoseconds; |
| 942 | } | 942 | } |
| 943 | |||
| 944 | /// Write number of nanoseconds according to its signed magnitude: | ||
| 945 | /// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` | ||
| 946 | pub fn format(duration: Duration, w: *Writer) Writer.Error!void { | ||
| 947 | if (duration.nanoseconds < 0) try w.writeByte('-'); | ||
| 948 | return formatUnsigned(w, @abs(duration.nanoseconds)); | ||
| 949 | } | ||
| 950 | |||
| 951 | fn formatUnsigned(w: *Writer, ns: u96) Writer.Error!void { | ||
| 952 | var ns_remaining = ns; | ||
| 953 | inline for (.{ | ||
| 954 | .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, | ||
| 955 | .{ .ns = std.time.ns_per_week, .sep = 'w' }, | ||
| 956 | .{ .ns = std.time.ns_per_day, .sep = 'd' }, | ||
| 957 | .{ .ns = std.time.ns_per_hour, .sep = 'h' }, | ||
| 958 | .{ .ns = std.time.ns_per_min, .sep = 'm' }, | ||
| 959 | }) |unit| { | ||
| 960 | if (ns_remaining >= unit.ns) { | ||
| 961 | const units = ns_remaining / unit.ns; | ||
| 962 | try w.printInt(units, 10, .lower, .{}); | ||
| 963 | try w.writeByte(unit.sep); | ||
| 964 | ns_remaining -= units * unit.ns; | ||
| 965 | if (ns_remaining == 0) return; | ||
| 966 | } | ||
| 967 | } | ||
| 968 | |||
| 969 | inline for (.{ | ||
| 970 | .{ .ns = std.time.ns_per_s, .sep = "s" }, | ||
| 971 | .{ .ns = std.time.ns_per_ms, .sep = "ms" }, | ||
| 972 | .{ .ns = std.time.ns_per_us, .sep = "us" }, | ||
| 973 | }) |unit| { | ||
| 974 | const kunits = ns_remaining * 1000 / unit.ns; | ||
| 975 | if (kunits >= 1000) { | ||
| 976 | try w.printInt(kunits / 1000, 10, .lower, .{}); | ||
| 977 | const frac = kunits % 1000; | ||
| 978 | if (frac > 0) { | ||
| 979 | // Write up to 3 decimal places | ||
| 980 | var decimal_buf = [_]u8{ '.', 0, 0, 0 }; | ||
| 981 | var inner: Writer = .fixed(decimal_buf[1..]); | ||
| 982 | inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; | ||
| 983 | var end: usize = 4; | ||
| 984 | while (end > 1) : (end -= 1) { | ||
| 985 | if (decimal_buf[end - 1] != '0') break; | ||
| 986 | } | ||
| 987 | try w.writeAll(decimal_buf[0..end]); | ||
| 988 | } | ||
| 989 | return w.writeAll(unit.sep); | ||
| 990 | } | ||
| 991 | } | ||
| 992 | |||
| 993 | try w.printInt(ns_remaining, 10, .lower, .{}); | ||
| 994 | try w.writeAll("ns"); | ||
| 995 | } | ||
| 996 | |||
| 997 | test format { | ||
| 998 | try testFormat("0ns", 0); | ||
| 999 | try testFormat("1ns", 1); | ||
| 1000 | try testFormat("-1ns", -(1)); | ||
| 1001 | try testFormat("999ns", std.time.ns_per_us - 1); | ||
| 1002 | try testFormat("-999ns", -(std.time.ns_per_us - 1)); | ||
| 1003 | try testFormat("1us", std.time.ns_per_us); | ||
| 1004 | try testFormat("-1us", -(std.time.ns_per_us)); | ||
| 1005 | try testFormat("1.45us", 1450); | ||
| 1006 | try testFormat("-1.45us", -(1450)); | ||
| 1007 | try testFormat("1.5us", 3 * std.time.ns_per_us / 2); | ||
| 1008 | try testFormat("-1.5us", -(3 * std.time.ns_per_us / 2)); | ||
| 1009 | try testFormat("14.5us", 14500); | ||
| 1010 | try testFormat("-14.5us", -(14500)); | ||
| 1011 | try testFormat("145us", 145000); | ||
| 1012 | try testFormat("-145us", -(145000)); | ||
| 1013 | try testFormat("999.999us", std.time.ns_per_ms - 1); | ||
| 1014 | try testFormat("-999.999us", -(std.time.ns_per_ms - 1)); | ||
| 1015 | try testFormat("1ms", std.time.ns_per_ms + 1); | ||
| 1016 | try testFormat("-1ms", -(std.time.ns_per_ms + 1)); | ||
| 1017 | try testFormat("1.5ms", 3 * std.time.ns_per_ms / 2); | ||
| 1018 | try testFormat("-1.5ms", -(3 * std.time.ns_per_ms / 2)); | ||
| 1019 | try testFormat("1.11ms", 1110000); | ||
| 1020 | try testFormat("-1.11ms", -(1110000)); | ||
| 1021 | try testFormat("1.111ms", 1111000); | ||
| 1022 | try testFormat("-1.111ms", -(1111000)); | ||
| 1023 | try testFormat("1.111ms", 1111100); | ||
| 1024 | try testFormat("-1.111ms", -(1111100)); | ||
| 1025 | try testFormat("999.999ms", std.time.ns_per_s - 1); | ||
| 1026 | try testFormat("-999.999ms", -(std.time.ns_per_s - 1)); | ||
| 1027 | try testFormat("1s", std.time.ns_per_s); | ||
| 1028 | try testFormat("-1s", -(std.time.ns_per_s)); | ||
| 1029 | try testFormat("59.999s", std.time.ns_per_min - 1); | ||
| 1030 | try testFormat("-59.999s", -(std.time.ns_per_min - 1)); | ||
| 1031 | try testFormat("1m", std.time.ns_per_min); | ||
| 1032 | try testFormat("-1m", -(std.time.ns_per_min)); | ||
| 1033 | try testFormat("1h", std.time.ns_per_hour); | ||
| 1034 | try testFormat("-1h", -(std.time.ns_per_hour)); | ||
| 1035 | try testFormat("1d", std.time.ns_per_day); | ||
| 1036 | try testFormat("-1d", -(std.time.ns_per_day)); | ||
| 1037 | try testFormat("1w", std.time.ns_per_week); | ||
| 1038 | try testFormat("-1w", -(std.time.ns_per_week)); | ||
| 1039 | try testFormat("1y", 365 * std.time.ns_per_day); | ||
| 1040 | try testFormat("-1y", -(365 * std.time.ns_per_day)); | ||
| 1041 | try testFormat("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d | ||
| 1042 | try testFormat("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d | ||
| 1043 | try testFormat("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | ||
| 1044 | try testFormat("-1y1h1.001s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms)); | ||
| 1045 | try testFormat("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | ||
| 1046 | try testFormat("-1y1h1s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us)); | ||
| 1047 | try testFormat("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | ||
| 1048 | try testFormat("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); | ||
| 1049 | try testFormat("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | ||
| 1050 | try testFormat("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); | ||
| 1051 | try testFormat("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | ||
| 1052 | try testFormat("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); | ||
| 1053 | try testFormat("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | ||
| 1054 | try testFormat("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); | ||
| 1055 | try testFormat("292y24w3d23h47m16.854s", std.math.maxInt(i64)); | ||
| 1056 | try testFormat("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); | ||
| 1057 | try testFormat("-292y24w3d23h47m16.854s", std.math.minInt(i64)); | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | fn testFormat(expected: []const u8, input: i96) !void { | ||
| 1061 | // worst case: "-XXXXXXXXXXXXXyXXwXXdXXhXXmXX.XXXs".len = 34 | ||
| 1062 | var buf: [34]u8 = undefined; | ||
| 1063 | var w: Writer = .fixed(&buf); | ||
| 1064 | try w.print("{f}", .{Duration{ .nanoseconds = input }}); | ||
| 1065 | try std.testing.expectEqualStrings(expected, w.buffered()); | ||
| 1066 | } | ||
| 943 | }; | 1067 | }; |
| 944 | 1068 | ||
| 945 | /// Declares under what conditions an operation should return `error.Timeout`. | 1069 | /// Declares under what conditions an operation should return `error.Timeout`. |
lib/std/Io/Writer.zig-195| ... | @@ -1155,11 +1155,6 @@ pub fn printValue( | ... | @@ -1155,11 +1155,6 @@ pub fn printValue( |
| 1155 | .@"struct" => return value.formatByteSize(w, .decimal), | 1155 | .@"struct" => return value.formatByteSize(w, .decimal), |
| 1156 | else => invalidFmtError(fmt, value), | 1156 | else => invalidFmtError(fmt, value), |
| 1157 | }, | 1157 | }, |
| 1158 | 'D' => switch (@typeInfo(T)) { | ||
| 1159 | .int, .comptime_int => return w.printDuration(value, options), | ||
| 1160 | .@"struct" => return value.formatDuration(w), | ||
| 1161 | else => invalidFmtError(fmt, value), | ||
| 1162 | }, | ||
| 1163 | 'e' => switch (@typeInfo(T)) { | 1158 | 'e' => switch (@typeInfo(T)) { |
| 1164 | .float, .comptime_float => return printFloat(w, value, options.toNumber(.scientific, .lower)), | 1159 | .float, .comptime_float => return printFloat(w, value, options.toNumber(.scientific, .lower)), |
| 1165 | .@"struct" => return value.formatNumber(w, options.toNumber(.scientific, .lower)), | 1160 | .@"struct" => return value.formatNumber(w, options.toNumber(.scientific, .lower)), |
| ... | @@ -1792,77 +1787,6 @@ pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn { | ... | @@ -1792,77 +1787,6 @@ pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn { |
| 1792 | @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); | 1787 | @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); |
| 1793 | } | 1788 | } |
| 1794 | 1789 | ||
| 1795 | pub fn printDurationSigned(w: *Writer, ns: i64) Error!void { | ||
| 1796 | if (ns < 0) try w.writeByte('-'); | ||
| 1797 | return w.printDurationUnsigned(@abs(ns)); | ||
| 1798 | } | ||
| 1799 | |||
| 1800 | pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void { | ||
| 1801 | var ns_remaining = ns; | ||
| 1802 | inline for (.{ | ||
| 1803 | .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, | ||
| 1804 | .{ .ns = std.time.ns_per_week, .sep = 'w' }, | ||
| 1805 | .{ .ns = std.time.ns_per_day, .sep = 'd' }, | ||
| 1806 | .{ .ns = std.time.ns_per_hour, .sep = 'h' }, | ||
| 1807 | .{ .ns = std.time.ns_per_min, .sep = 'm' }, | ||
| 1808 | }) |unit| { | ||
| 1809 | if (ns_remaining >= unit.ns) { | ||
| 1810 | const units = ns_remaining / unit.ns; | ||
| 1811 | try w.printInt(units, 10, .lower, .{}); | ||
| 1812 | try w.writeByte(unit.sep); | ||
| 1813 | ns_remaining -= units * unit.ns; | ||
| 1814 | if (ns_remaining == 0) return; | ||
| 1815 | } | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | inline for (.{ | ||
| 1819 | .{ .ns = std.time.ns_per_s, .sep = "s" }, | ||
| 1820 | .{ .ns = std.time.ns_per_ms, .sep = "ms" }, | ||
| 1821 | .{ .ns = std.time.ns_per_us, .sep = "us" }, | ||
| 1822 | }) |unit| { | ||
| 1823 | const kunits = ns_remaining * 1000 / unit.ns; | ||
| 1824 | if (kunits >= 1000) { | ||
| 1825 | try w.printInt(kunits / 1000, 10, .lower, .{}); | ||
| 1826 | const frac = kunits % 1000; | ||
| 1827 | if (frac > 0) { | ||
| 1828 | // Write up to 3 decimal places | ||
| 1829 | var decimal_buf = [_]u8{ '.', 0, 0, 0 }; | ||
| 1830 | var inner: Writer = .fixed(decimal_buf[1..]); | ||
| 1831 | inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; | ||
| 1832 | var end: usize = 4; | ||
| 1833 | while (end > 1) : (end -= 1) { | ||
| 1834 | if (decimal_buf[end - 1] != '0') break; | ||
| 1835 | } | ||
| 1836 | try w.writeAll(decimal_buf[0..end]); | ||
| 1837 | } | ||
| 1838 | return w.writeAll(unit.sep); | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | try w.printInt(ns_remaining, 10, .lower, .{}); | ||
| 1843 | try w.writeAll("ns"); | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | /// Writes number of nanoseconds according to its signed magnitude: | ||
| 1847 | /// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` | ||
| 1848 | /// `nanoseconds` must be an integer that coerces into `u64` or `i64`. | ||
| 1849 | pub fn printDuration(w: *Writer, nanoseconds: anytype, options: std.fmt.Options) Error!void { | ||
| 1850 | // worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24 | ||
| 1851 | var buf: [24]u8 = undefined; | ||
| 1852 | var sub_writer: Writer = .fixed(&buf); | ||
| 1853 | if (@TypeOf(nanoseconds) == comptime_int) { | ||
| 1854 | if (nanoseconds >= 0) { | ||
| 1855 | sub_writer.printDurationUnsigned(nanoseconds) catch unreachable; | ||
| 1856 | } else { | ||
| 1857 | sub_writer.printDurationSigned(nanoseconds) catch unreachable; | ||
| 1858 | } | ||
| 1859 | } else switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) { | ||
| 1860 | .signed => sub_writer.printDurationSigned(nanoseconds) catch unreachable, | ||
| 1861 | .unsigned => sub_writer.printDurationUnsigned(nanoseconds) catch unreachable, | ||
| 1862 | } | ||
| 1863 | return w.alignBufferOptions(sub_writer.buffered(), options); | ||
| 1864 | } | ||
| 1865 | |||
| 1866 | pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void { | 1790 | pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void { |
| 1867 | const charset = switch (case) { | 1791 | const charset = switch (case) { |
| 1868 | .upper => "0123456789ABCDEF", | 1792 | .upper => "0123456789ABCDEF", |
| ... | @@ -2129,125 +2053,6 @@ test "printValue max_depth" { | ... | @@ -2129,125 +2053,6 @@ test "printValue max_depth" { |
| 2129 | try testing.expectEqualStrings("{ 1, 2, 3, 4 }", w.buffered()); | 2053 | try testing.expectEqualStrings("{ 1, 2, 3, 4 }", w.buffered()); |
| 2130 | } | 2054 | } |
| 2131 | 2055 | ||
| 2132 | test printDuration { | ||
| 2133 | try testDurationCase("0ns", 0); | ||
| 2134 | try testDurationCase("1ns", 1); | ||
| 2135 | try testDurationCase("999ns", std.time.ns_per_us - 1); | ||
| 2136 | try testDurationCase("1us", std.time.ns_per_us); | ||
| 2137 | try testDurationCase("1.45us", 1450); | ||
| 2138 | try testDurationCase("1.5us", 3 * std.time.ns_per_us / 2); | ||
| 2139 | try testDurationCase("14.5us", 14500); | ||
| 2140 | try testDurationCase("145us", 145000); | ||
| 2141 | try testDurationCase("999.999us", std.time.ns_per_ms - 1); | ||
| 2142 | try testDurationCase("1ms", std.time.ns_per_ms + 1); | ||
| 2143 | try testDurationCase("1.5ms", 3 * std.time.ns_per_ms / 2); | ||
| 2144 | try testDurationCase("1.11ms", 1110000); | ||
| 2145 | try testDurationCase("1.111ms", 1111000); | ||
| 2146 | try testDurationCase("1.111ms", 1111100); | ||
| 2147 | try testDurationCase("999.999ms", std.time.ns_per_s - 1); | ||
| 2148 | try testDurationCase("1s", std.time.ns_per_s); | ||
| 2149 | try testDurationCase("59.999s", std.time.ns_per_min - 1); | ||
| 2150 | try testDurationCase("1m", std.time.ns_per_min); | ||
| 2151 | try testDurationCase("1h", std.time.ns_per_hour); | ||
| 2152 | try testDurationCase("1d", std.time.ns_per_day); | ||
| 2153 | try testDurationCase("1w", std.time.ns_per_week); | ||
| 2154 | try testDurationCase("1y", 365 * std.time.ns_per_day); | ||
| 2155 | try testDurationCase("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1 | ||
| 2156 | try testDurationCase("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | ||
| 2157 | try testDurationCase("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | ||
| 2158 | try testDurationCase("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | ||
| 2159 | try testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | ||
| 2160 | try testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | ||
| 2161 | try testDurationCase("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | ||
| 2162 | try testDurationCase("584y49w23h34m33.709s", std.math.maxInt(u64)); | ||
| 2163 | |||
| 2164 | try testing.expectFmt("=======0ns", "{D:=>10}", .{0}); | ||
| 2165 | try testing.expectFmt("1ns=======", "{D:=<10}", .{1}); | ||
| 2166 | try testing.expectFmt(" 999ns ", "{D:^10}", .{std.time.ns_per_us - 1}); | ||
| 2167 | } | ||
| 2168 | |||
| 2169 | test printDurationSigned { | ||
| 2170 | try testDurationCaseSigned("0ns", 0); | ||
| 2171 | try testDurationCaseSigned("1ns", 1); | ||
| 2172 | try testDurationCaseSigned("-1ns", -(1)); | ||
| 2173 | try testDurationCaseSigned("999ns", std.time.ns_per_us - 1); | ||
| 2174 | try testDurationCaseSigned("-999ns", -(std.time.ns_per_us - 1)); | ||
| 2175 | try testDurationCaseSigned("1us", std.time.ns_per_us); | ||
| 2176 | try testDurationCaseSigned("-1us", -(std.time.ns_per_us)); | ||
| 2177 | try testDurationCaseSigned("1.45us", 1450); | ||
| 2178 | try testDurationCaseSigned("-1.45us", -(1450)); | ||
| 2179 | try testDurationCaseSigned("1.5us", 3 * std.time.ns_per_us / 2); | ||
| 2180 | try testDurationCaseSigned("-1.5us", -(3 * std.time.ns_per_us / 2)); | ||
| 2181 | try testDurationCaseSigned("14.5us", 14500); | ||
| 2182 | try testDurationCaseSigned("-14.5us", -(14500)); | ||
| 2183 | try testDurationCaseSigned("145us", 145000); | ||
| 2184 | try testDurationCaseSigned("-145us", -(145000)); | ||
| 2185 | try testDurationCaseSigned("999.999us", std.time.ns_per_ms - 1); | ||
| 2186 | try testDurationCaseSigned("-999.999us", -(std.time.ns_per_ms - 1)); | ||
| 2187 | try testDurationCaseSigned("1ms", std.time.ns_per_ms + 1); | ||
| 2188 | try testDurationCaseSigned("-1ms", -(std.time.ns_per_ms + 1)); | ||
| 2189 | try testDurationCaseSigned("1.5ms", 3 * std.time.ns_per_ms / 2); | ||
| 2190 | try testDurationCaseSigned("-1.5ms", -(3 * std.time.ns_per_ms / 2)); | ||
| 2191 | try testDurationCaseSigned("1.11ms", 1110000); | ||
| 2192 | try testDurationCaseSigned("-1.11ms", -(1110000)); | ||
| 2193 | try testDurationCaseSigned("1.111ms", 1111000); | ||
| 2194 | try testDurationCaseSigned("-1.111ms", -(1111000)); | ||
| 2195 | try testDurationCaseSigned("1.111ms", 1111100); | ||
| 2196 | try testDurationCaseSigned("-1.111ms", -(1111100)); | ||
| 2197 | try testDurationCaseSigned("999.999ms", std.time.ns_per_s - 1); | ||
| 2198 | try testDurationCaseSigned("-999.999ms", -(std.time.ns_per_s - 1)); | ||
| 2199 | try testDurationCaseSigned("1s", std.time.ns_per_s); | ||
| 2200 | try testDurationCaseSigned("-1s", -(std.time.ns_per_s)); | ||
| 2201 | try testDurationCaseSigned("59.999s", std.time.ns_per_min - 1); | ||
| 2202 | try testDurationCaseSigned("-59.999s", -(std.time.ns_per_min - 1)); | ||
| 2203 | try testDurationCaseSigned("1m", std.time.ns_per_min); | ||
| 2204 | try testDurationCaseSigned("-1m", -(std.time.ns_per_min)); | ||
| 2205 | try testDurationCaseSigned("1h", std.time.ns_per_hour); | ||
| 2206 | try testDurationCaseSigned("-1h", -(std.time.ns_per_hour)); | ||
| 2207 | try testDurationCaseSigned("1d", std.time.ns_per_day); | ||
| 2208 | try testDurationCaseSigned("-1d", -(std.time.ns_per_day)); | ||
| 2209 | try testDurationCaseSigned("1w", std.time.ns_per_week); | ||
| 2210 | try testDurationCaseSigned("-1w", -(std.time.ns_per_week)); | ||
| 2211 | try testDurationCaseSigned("1y", 365 * std.time.ns_per_day); | ||
| 2212 | try testDurationCaseSigned("-1y", -(365 * std.time.ns_per_day)); | ||
| 2213 | try testDurationCaseSigned("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d | ||
| 2214 | try testDurationCaseSigned("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d | ||
| 2215 | try testDurationCaseSigned("1y1h1.001s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms); | ||
| 2216 | try testDurationCaseSigned("-1y1h1.001s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms)); | ||
| 2217 | try testDurationCaseSigned("1y1h1s", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us); | ||
| 2218 | try testDurationCaseSigned("-1y1h1s", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us)); | ||
| 2219 | try testDurationCaseSigned("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); | ||
| 2220 | try testDurationCaseSigned("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); | ||
| 2221 | try testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); | ||
| 2222 | try testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); | ||
| 2223 | try testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); | ||
| 2224 | try testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); | ||
| 2225 | try testDurationCaseSigned("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); | ||
| 2226 | try testDurationCaseSigned("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); | ||
| 2227 | try testDurationCaseSigned("292y24w3d23h47m16.854s", std.math.maxInt(i64)); | ||
| 2228 | try testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); | ||
| 2229 | try testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64)); | ||
| 2230 | |||
| 2231 | try testing.expectFmt("=======0ns", "{D:=>10}", .{0}); | ||
| 2232 | try testing.expectFmt("1ns=======", "{D:=<10}", .{1}); | ||
| 2233 | try testing.expectFmt("-1ns======", "{D:=<10}", .{-(1)}); | ||
| 2234 | try testing.expectFmt(" -999ns ", "{D:^10}", .{-(std.time.ns_per_us - 1)}); | ||
| 2235 | } | ||
| 2236 | |||
| 2237 | fn testDurationCase(expected: []const u8, input: u64) !void { | ||
| 2238 | var buf: [24]u8 = undefined; | ||
| 2239 | var w: Writer = .fixed(&buf); | ||
| 2240 | try w.printDurationUnsigned(input); | ||
| 2241 | try testing.expectEqualStrings(expected, w.buffered()); | ||
| 2242 | } | ||
| 2243 | |||
| 2244 | fn testDurationCaseSigned(expected: []const u8, input: i64) !void { | ||
| 2245 | var buf: [24]u8 = undefined; | ||
| 2246 | var w: Writer = .fixed(&buf); | ||
| 2247 | try w.printDurationSigned(input); | ||
| 2248 | try testing.expectEqualStrings(expected, w.buffered()); | ||
| 2249 | } | ||
| 2250 | |||
| 2251 | test printInt { | 2056 | test printInt { |
| 2252 | try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{}); | 2057 | try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{}); |
| 2253 | 2058 |