From 99229ceb55be717aa1995f1a0105bc6b96a910f6 Mon Sep 17 00:00:00 2001 From: hemisputnik Date: Fri, 27 Feb 2026 01:19:20 +0200 Subject: [PATCH] std.Io.{Writer|Duration}: move duration formatting to a format method 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 #31281 --- lib/build-web/time_report.zig | 78 +++++++------- lib/std/Build/Step/Run.zig | 6 +- lib/std/Io.zig | 124 +++++++++++++++++++++ lib/std/Io/Writer.zig | 195 ---------------------------------- 4 files changed, 166 insertions(+), 237 deletions(-) diff --git a/lib/build-web/time_report.zig b/lib/build-web/time_report.zig index c19a5abcc9ff7690a0bad35d19105b07f14f0db8..f6e641432c93f7c2dc60cc710903ee907f25c626 100644 --- a/lib/build-web/time_report.zig +++ b/lib/build-web/time_report.zig @@ -42,10 +42,10 @@ pub fn genericResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { if (msg.step_idx >= step_list.*.len) @panic("malformed GenericResult message"); const inner_html = try std.fmt.allocPrint(gpa, \\{[step_name]f} - \\{[stat_total_time]D} + \\{[stat_total_time]f} , .{ .step_name = fmtEscapeHtml(step_list.*[msg.step_idx].name), - .stat_total_time = msg.ns_total, + .stat_total_time = std.Io.Duration{ .nanoseconds = msg.ns_total }, }); defer gpa.free(inner_html); 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 \\{[stat_imported_files]d} \\{[stat_generic_instances]d} \\{[stat_inline_calls]d} - \\{[stat_compilation_time]D} - \\{[cpu_time_parse]D} - \\{[cpu_time_astgen]D} - \\{[cpu_time_sema]D} - \\{[cpu_time_codegen]D} - \\{[cpu_time_link]D} - \\{[real_time_files]D} - \\{[real_time_decls]D} - \\{[real_time_llvm_emit]D} - \\{[real_time_link_flush]D} + \\{[stat_compilation_time]f} + \\{[cpu_time_parse]f} + \\{[cpu_time_astgen]f} + \\{[cpu_time_sema]f} + \\{[cpu_time_codegen]f} + \\{[cpu_time_link]f} + \\{[real_time_files]f} + \\{[real_time_decls]f} + \\{[real_time_llvm_emit]f} + \\{[real_time_link_flush]f} \\
{[llvm_pass_timings]f}
\\ , .{ @@ -157,17 +157,17 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v .stat_imported_files = stats.n_imported_files, .stat_generic_instances = stats.n_generic_instances, .stat_inline_calls = stats.n_inline_calls, - .stat_compilation_time = hdr.ns_total, + .stat_compilation_time = std.Io.Duration{ .nanoseconds = hdr.ns_total }, - .cpu_time_parse = stats.cpu_ns_parse, - .cpu_time_astgen = stats.cpu_ns_astgen, - .cpu_time_sema = stats.cpu_ns_sema, - .cpu_time_codegen = stats.cpu_ns_codegen, - .cpu_time_link = stats.cpu_ns_link, - .real_time_files = stats.real_ns_files, - .real_time_decls = stats.real_ns_decls, - .real_time_llvm_emit = stats.real_ns_llvm_emit, - .real_time_link_flush = stats.real_ns_link_flush, + .cpu_time_parse = std.Io.Duration{ .nanoseconds = stats.cpu_ns_parse }, + .cpu_time_astgen = std.Io.Duration{ .nanoseconds = stats.cpu_ns_astgen }, + .cpu_time_sema = std.Io.Duration{ .nanoseconds = stats.cpu_ns_sema }, + .cpu_time_codegen = std.Io.Duration{ .nanoseconds = stats.cpu_ns_codegen }, + .cpu_time_link = std.Io.Duration{ .nanoseconds = stats.cpu_ns_link }, + .real_time_files = std.Io.Duration{ .nanoseconds = stats.real_ns_files }, + .real_time_decls = std.Io.Duration{ .nanoseconds = stats.real_ns_decls }, + .real_time_llvm_emit = std.Io.Duration{ .nanoseconds = stats.real_ns_llvm_emit }, + .real_time_link_flush = std.Io.Duration{ .nanoseconds = stats.real_ns_link_flush }, .llvm_pass_timings = fmtEscapeHtml(llvm_pass_timings), }); @@ -180,18 +180,18 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v try file_table_html.writer.print( \\ \\ {f} - \\ {D} - \\ {D} - \\ {D} - \\ {D} + \\ {f} + \\ {f} + \\ {f} + \\ {f} \\ \\ , .{ fmtEscapeHtml(file.name), - file.ns_sema, - file.ns_codegen, - file.ns_link, - file.ns_sema + file.ns_codegen + file.ns_link, + std.Io.Duration{ .nanoseconds = file.ns_sema }, + std.Io.Duration{ .nanoseconds = file.ns_codegen }, + std.Io.Duration{ .nanoseconds = file.ns_link }, + std.Io.Duration{ .nanoseconds = file.ns_sema + file.ns_codegen + file.ns_link }, }); } if (slowest_files.len > max_table_rows) { @@ -210,20 +210,20 @@ pub fn compileResultMessage(msg_bytes: []u8) error{ OutOfMemory, WriteFailed }!v \\ {f} \\ {f} \\ {d} - \\ {D} - \\ {D} - \\ {D} - \\ {D} + \\ {f} + \\ {f} + \\ {f} + \\ {f} \\ \\ , .{ fmtEscapeHtml(decl.file_name), fmtEscapeHtml(decl.name), decl.sema_count, - decl.ns_sema, - decl.ns_codegen, - decl.ns_link, - decl.ns_sema + decl.ns_codegen + decl.ns_link, + std.Io.Duration{ .nanoseconds = decl.ns_sema }, + std.Io.Duration{ .nanoseconds = decl.ns_codegen }, + std.Io.Duration{ .nanoseconds = decl.ns_link }, + std.Io.Duration{ .nanoseconds = decl.ns_sema + decl.ns_codegen + decl.ns_link }, }); } if (slowest_decls.len > max_table_rows) { @@ -265,7 +265,7 @@ pub fn runTestResultMessage(msg_bytes: []u8) error{OutOfMemory}!void { if (test_ns == std.math.maxInt(u64)) { try table_html.appendSlice(gpa, ""); // didn't run } else { - try table_html.print(gpa, "{D}", .{test_ns}); + try table_html.print(gpa, "{f}", .{std.Io.Duration{ .nanoseconds = test_ns }}); } try table_html.appendSlice(gpa, "\n"); } diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index e80f57f0bc33db759b32ef03b37c5a355e680f84..8a21e6fef9b3da523b2ad087008b805c7da0e676 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -1787,9 +1787,9 @@ fn evalZigTest( // the next test. test_metadata.?.ns_per_test[test_index] = timeout.ns_elapsed; test_results.timeout_count += 1; - try run.step.addError("'{s}' timed out after {D}{s}{s}", .{ + try run.step.addError("'{s}' timed out after {f}{s}{s}", .{ test_metadata.?.testName(test_index), - timeout.ns_elapsed, + Io.Duration{ .nanoseconds = timeout.ns_elapsed }, if (stderr.len != 0) " with stderr:\n" else "", std.mem.trim(u8, stderr, "\n"), }); @@ -1799,7 +1799,7 @@ fn evalZigTest( run.step.result_stderr = try arena.dupe(u8, stderr); // The individual unit test results in `results` are irrelevant: the test runner // is broken! Fail immediately without populating `s.test_results`. - return run.step.fail("test runner failed to respond for {D}", .{timeout.ns_elapsed}); + return run.step.fail("test runner failed to respond for {f}", .{Io.Duration{ .nanoseconds = timeout.ns_elapsed }}); }, } comptime unreachable; diff --git a/lib/std/Io.zig b/lib/std/Io.zig index a5584da61e145f053f85b86fecfe8385abb992dc..88813e8ae85eb8aca53a01d4f0a6b3302e8fa43d 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -940,6 +940,130 @@ pub const Duration = struct { pub fn toNanoseconds(d: Duration) i96 { return d.nanoseconds; } + + /// Write number of nanoseconds according to its signed magnitude: + /// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` + pub fn format(duration: Duration, w: *Writer) Writer.Error!void { + if (duration.nanoseconds < 0) try w.writeByte('-'); + return formatUnsigned(w, @abs(duration.nanoseconds)); + } + + fn formatUnsigned(w: *Writer, ns: u96) Writer.Error!void { + var ns_remaining = ns; + inline for (.{ + .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, + .{ .ns = std.time.ns_per_week, .sep = 'w' }, + .{ .ns = std.time.ns_per_day, .sep = 'd' }, + .{ .ns = std.time.ns_per_hour, .sep = 'h' }, + .{ .ns = std.time.ns_per_min, .sep = 'm' }, + }) |unit| { + if (ns_remaining >= unit.ns) { + const units = ns_remaining / unit.ns; + try w.printInt(units, 10, .lower, .{}); + try w.writeByte(unit.sep); + ns_remaining -= units * unit.ns; + if (ns_remaining == 0) return; + } + } + + inline for (.{ + .{ .ns = std.time.ns_per_s, .sep = "s" }, + .{ .ns = std.time.ns_per_ms, .sep = "ms" }, + .{ .ns = std.time.ns_per_us, .sep = "us" }, + }) |unit| { + const kunits = ns_remaining * 1000 / unit.ns; + if (kunits >= 1000) { + try w.printInt(kunits / 1000, 10, .lower, .{}); + const frac = kunits % 1000; + if (frac > 0) { + // Write up to 3 decimal places + var decimal_buf = [_]u8{ '.', 0, 0, 0 }; + var inner: Writer = .fixed(decimal_buf[1..]); + inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; + var end: usize = 4; + while (end > 1) : (end -= 1) { + if (decimal_buf[end - 1] != '0') break; + } + try w.writeAll(decimal_buf[0..end]); + } + return w.writeAll(unit.sep); + } + } + + try w.printInt(ns_remaining, 10, .lower, .{}); + try w.writeAll("ns"); + } + + test format { + try testFormat("0ns", 0); + try testFormat("1ns", 1); + try testFormat("-1ns", -(1)); + try testFormat("999ns", std.time.ns_per_us - 1); + try testFormat("-999ns", -(std.time.ns_per_us - 1)); + try testFormat("1us", std.time.ns_per_us); + try testFormat("-1us", -(std.time.ns_per_us)); + try testFormat("1.45us", 1450); + try testFormat("-1.45us", -(1450)); + try testFormat("1.5us", 3 * std.time.ns_per_us / 2); + try testFormat("-1.5us", -(3 * std.time.ns_per_us / 2)); + try testFormat("14.5us", 14500); + try testFormat("-14.5us", -(14500)); + try testFormat("145us", 145000); + try testFormat("-145us", -(145000)); + try testFormat("999.999us", std.time.ns_per_ms - 1); + try testFormat("-999.999us", -(std.time.ns_per_ms - 1)); + try testFormat("1ms", std.time.ns_per_ms + 1); + try testFormat("-1ms", -(std.time.ns_per_ms + 1)); + try testFormat("1.5ms", 3 * std.time.ns_per_ms / 2); + try testFormat("-1.5ms", -(3 * std.time.ns_per_ms / 2)); + try testFormat("1.11ms", 1110000); + try testFormat("-1.11ms", -(1110000)); + try testFormat("1.111ms", 1111000); + try testFormat("-1.111ms", -(1111000)); + try testFormat("1.111ms", 1111100); + try testFormat("-1.111ms", -(1111100)); + try testFormat("999.999ms", std.time.ns_per_s - 1); + try testFormat("-999.999ms", -(std.time.ns_per_s - 1)); + try testFormat("1s", std.time.ns_per_s); + try testFormat("-1s", -(std.time.ns_per_s)); + try testFormat("59.999s", std.time.ns_per_min - 1); + try testFormat("-59.999s", -(std.time.ns_per_min - 1)); + try testFormat("1m", std.time.ns_per_min); + try testFormat("-1m", -(std.time.ns_per_min)); + try testFormat("1h", std.time.ns_per_hour); + try testFormat("-1h", -(std.time.ns_per_hour)); + try testFormat("1d", std.time.ns_per_day); + try testFormat("-1d", -(std.time.ns_per_day)); + try testFormat("1w", std.time.ns_per_week); + try testFormat("-1w", -(std.time.ns_per_week)); + try testFormat("1y", 365 * std.time.ns_per_day); + try testFormat("-1y", -(365 * std.time.ns_per_day)); + try testFormat("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d + try testFormat("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d + 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); + 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)); + 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); + 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)); + try testFormat("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); + try testFormat("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); + try testFormat("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); + try testFormat("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); + try testFormat("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); + try testFormat("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); + try testFormat("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); + try testFormat("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); + try testFormat("292y24w3d23h47m16.854s", std.math.maxInt(i64)); + try testFormat("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); + try testFormat("-292y24w3d23h47m16.854s", std.math.minInt(i64)); + } + + fn testFormat(expected: []const u8, input: i96) !void { + // worst case: "-XXXXXXXXXXXXXyXXwXXdXXhXXmXX.XXXs".len = 34 + var buf: [34]u8 = undefined; + var w: Writer = .fixed(&buf); + try w.print("{f}", .{Duration{ .nanoseconds = input }}); + try std.testing.expectEqualStrings(expected, w.buffered()); + } }; /// Declares under what conditions an operation should return `error.Timeout`. diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index b7da83f3a0f1ea911d2de792a468353afd34c97e..d1cea560c3611fc760f524041daac22fdf586147 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -1155,11 +1155,6 @@ pub fn printValue( .@"struct" => return value.formatByteSize(w, .decimal), else => invalidFmtError(fmt, value), }, - 'D' => switch (@typeInfo(T)) { - .int, .comptime_int => return w.printDuration(value, options), - .@"struct" => return value.formatDuration(w), - else => invalidFmtError(fmt, value), - }, 'e' => switch (@typeInfo(T)) { .float, .comptime_float => return printFloat(w, value, options.toNumber(.scientific, .lower)), .@"struct" => return value.formatNumber(w, options.toNumber(.scientific, .lower)), @@ -1792,77 +1787,6 @@ pub fn invalidFmtError(comptime fmt: []const u8, value: anytype) noreturn { @compileError("invalid format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'"); } -pub fn printDurationSigned(w: *Writer, ns: i64) Error!void { - if (ns < 0) try w.writeByte('-'); - return w.printDurationUnsigned(@abs(ns)); -} - -pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void { - var ns_remaining = ns; - inline for (.{ - .{ .ns = 365 * std.time.ns_per_day, .sep = 'y' }, - .{ .ns = std.time.ns_per_week, .sep = 'w' }, - .{ .ns = std.time.ns_per_day, .sep = 'd' }, - .{ .ns = std.time.ns_per_hour, .sep = 'h' }, - .{ .ns = std.time.ns_per_min, .sep = 'm' }, - }) |unit| { - if (ns_remaining >= unit.ns) { - const units = ns_remaining / unit.ns; - try w.printInt(units, 10, .lower, .{}); - try w.writeByte(unit.sep); - ns_remaining -= units * unit.ns; - if (ns_remaining == 0) return; - } - } - - inline for (.{ - .{ .ns = std.time.ns_per_s, .sep = "s" }, - .{ .ns = std.time.ns_per_ms, .sep = "ms" }, - .{ .ns = std.time.ns_per_us, .sep = "us" }, - }) |unit| { - const kunits = ns_remaining * 1000 / unit.ns; - if (kunits >= 1000) { - try w.printInt(kunits / 1000, 10, .lower, .{}); - const frac = kunits % 1000; - if (frac > 0) { - // Write up to 3 decimal places - var decimal_buf = [_]u8{ '.', 0, 0, 0 }; - var inner: Writer = .fixed(decimal_buf[1..]); - inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable; - var end: usize = 4; - while (end > 1) : (end -= 1) { - if (decimal_buf[end - 1] != '0') break; - } - try w.writeAll(decimal_buf[0..end]); - } - return w.writeAll(unit.sep); - } - } - - try w.printInt(ns_remaining, 10, .lower, .{}); - try w.writeAll("ns"); -} - -/// Writes number of nanoseconds according to its signed magnitude: -/// `[#y][#w][#d][#h][#m]#[.###][n|u|m]s` -/// `nanoseconds` must be an integer that coerces into `u64` or `i64`. -pub fn printDuration(w: *Writer, nanoseconds: anytype, options: std.fmt.Options) Error!void { - // worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24 - var buf: [24]u8 = undefined; - var sub_writer: Writer = .fixed(&buf); - if (@TypeOf(nanoseconds) == comptime_int) { - if (nanoseconds >= 0) { - sub_writer.printDurationUnsigned(nanoseconds) catch unreachable; - } else { - sub_writer.printDurationSigned(nanoseconds) catch unreachable; - } - } else switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) { - .signed => sub_writer.printDurationSigned(nanoseconds) catch unreachable, - .unsigned => sub_writer.printDurationUnsigned(nanoseconds) catch unreachable, - } - return w.alignBufferOptions(sub_writer.buffered(), options); -} - pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void { const charset = switch (case) { .upper => "0123456789ABCDEF", @@ -2129,125 +2053,6 @@ test "printValue max_depth" { try testing.expectEqualStrings("{ 1, 2, 3, 4 }", w.buffered()); } -test printDuration { - try testDurationCase("0ns", 0); - try testDurationCase("1ns", 1); - try testDurationCase("999ns", std.time.ns_per_us - 1); - try testDurationCase("1us", std.time.ns_per_us); - try testDurationCase("1.45us", 1450); - try testDurationCase("1.5us", 3 * std.time.ns_per_us / 2); - try testDurationCase("14.5us", 14500); - try testDurationCase("145us", 145000); - try testDurationCase("999.999us", std.time.ns_per_ms - 1); - try testDurationCase("1ms", std.time.ns_per_ms + 1); - try testDurationCase("1.5ms", 3 * std.time.ns_per_ms / 2); - try testDurationCase("1.11ms", 1110000); - try testDurationCase("1.111ms", 1111000); - try testDurationCase("1.111ms", 1111100); - try testDurationCase("999.999ms", std.time.ns_per_s - 1); - try testDurationCase("1s", std.time.ns_per_s); - try testDurationCase("59.999s", std.time.ns_per_min - 1); - try testDurationCase("1m", std.time.ns_per_min); - try testDurationCase("1h", std.time.ns_per_hour); - try testDurationCase("1d", std.time.ns_per_day); - try testDurationCase("1w", std.time.ns_per_week); - try testDurationCase("1y", 365 * std.time.ns_per_day); - try testDurationCase("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1 - 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); - 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); - try testDurationCase("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); - try testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); - try testDurationCase("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); - try testDurationCase("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); - try testDurationCase("584y49w23h34m33.709s", std.math.maxInt(u64)); - - try testing.expectFmt("=======0ns", "{D:=>10}", .{0}); - try testing.expectFmt("1ns=======", "{D:=<10}", .{1}); - try testing.expectFmt(" 999ns ", "{D:^10}", .{std.time.ns_per_us - 1}); -} - -test printDurationSigned { - try testDurationCaseSigned("0ns", 0); - try testDurationCaseSigned("1ns", 1); - try testDurationCaseSigned("-1ns", -(1)); - try testDurationCaseSigned("999ns", std.time.ns_per_us - 1); - try testDurationCaseSigned("-999ns", -(std.time.ns_per_us - 1)); - try testDurationCaseSigned("1us", std.time.ns_per_us); - try testDurationCaseSigned("-1us", -(std.time.ns_per_us)); - try testDurationCaseSigned("1.45us", 1450); - try testDurationCaseSigned("-1.45us", -(1450)); - try testDurationCaseSigned("1.5us", 3 * std.time.ns_per_us / 2); - try testDurationCaseSigned("-1.5us", -(3 * std.time.ns_per_us / 2)); - try testDurationCaseSigned("14.5us", 14500); - try testDurationCaseSigned("-14.5us", -(14500)); - try testDurationCaseSigned("145us", 145000); - try testDurationCaseSigned("-145us", -(145000)); - try testDurationCaseSigned("999.999us", std.time.ns_per_ms - 1); - try testDurationCaseSigned("-999.999us", -(std.time.ns_per_ms - 1)); - try testDurationCaseSigned("1ms", std.time.ns_per_ms + 1); - try testDurationCaseSigned("-1ms", -(std.time.ns_per_ms + 1)); - try testDurationCaseSigned("1.5ms", 3 * std.time.ns_per_ms / 2); - try testDurationCaseSigned("-1.5ms", -(3 * std.time.ns_per_ms / 2)); - try testDurationCaseSigned("1.11ms", 1110000); - try testDurationCaseSigned("-1.11ms", -(1110000)); - try testDurationCaseSigned("1.111ms", 1111000); - try testDurationCaseSigned("-1.111ms", -(1111000)); - try testDurationCaseSigned("1.111ms", 1111100); - try testDurationCaseSigned("-1.111ms", -(1111100)); - try testDurationCaseSigned("999.999ms", std.time.ns_per_s - 1); - try testDurationCaseSigned("-999.999ms", -(std.time.ns_per_s - 1)); - try testDurationCaseSigned("1s", std.time.ns_per_s); - try testDurationCaseSigned("-1s", -(std.time.ns_per_s)); - try testDurationCaseSigned("59.999s", std.time.ns_per_min - 1); - try testDurationCaseSigned("-59.999s", -(std.time.ns_per_min - 1)); - try testDurationCaseSigned("1m", std.time.ns_per_min); - try testDurationCaseSigned("-1m", -(std.time.ns_per_min)); - try testDurationCaseSigned("1h", std.time.ns_per_hour); - try testDurationCaseSigned("-1h", -(std.time.ns_per_hour)); - try testDurationCaseSigned("1d", std.time.ns_per_day); - try testDurationCaseSigned("-1d", -(std.time.ns_per_day)); - try testDurationCaseSigned("1w", std.time.ns_per_week); - try testDurationCaseSigned("-1w", -(std.time.ns_per_week)); - try testDurationCaseSigned("1y", 365 * std.time.ns_per_day); - try testDurationCaseSigned("-1y", -(365 * std.time.ns_per_day)); - try testDurationCaseSigned("1y52w23h59m59.999s", 730 * std.time.ns_per_day - 1); // 365d = 52w1d - try testDurationCaseSigned("-1y52w23h59m59.999s", -(730 * std.time.ns_per_day - 1)); // 365d = 52w1d - 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); - 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)); - 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); - 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)); - try testDurationCaseSigned("1y1h999.999us", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1); - try testDurationCaseSigned("-1y1h999.999us", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1)); - try testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms); - try testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms)); - try testDurationCaseSigned("1y1h1ms", 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1); - try testDurationCaseSigned("-1y1h1ms", -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1)); - try testDurationCaseSigned("1y1m999ns", 365 * std.time.ns_per_day + std.time.ns_per_min + 999); - try testDurationCaseSigned("-1y1m999ns", -(365 * std.time.ns_per_day + std.time.ns_per_min + 999)); - try testDurationCaseSigned("292y24w3d23h47m16.854s", std.math.maxInt(i64)); - try testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64) + 1); - try testDurationCaseSigned("-292y24w3d23h47m16.854s", std.math.minInt(i64)); - - try testing.expectFmt("=======0ns", "{D:=>10}", .{0}); - try testing.expectFmt("1ns=======", "{D:=<10}", .{1}); - try testing.expectFmt("-1ns======", "{D:=<10}", .{-(1)}); - try testing.expectFmt(" -999ns ", "{D:^10}", .{-(std.time.ns_per_us - 1)}); -} - -fn testDurationCase(expected: []const u8, input: u64) !void { - var buf: [24]u8 = undefined; - var w: Writer = .fixed(&buf); - try w.printDurationUnsigned(input); - try testing.expectEqualStrings(expected, w.buffered()); -} - -fn testDurationCaseSigned(expected: []const u8, input: i64) !void { - var buf: [24]u8 = undefined; - var w: Writer = .fixed(&buf); - try w.printDurationSigned(input); - try testing.expectEqualStrings(expected, w.buffered()); -} - test printInt { try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{}); -- 2.54.0