zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit f398ac3ee48b35754f51f0bfaff76b6a1e70da77 (tree)
parent ef56e42a2a69e85d185257c5bd0b3f12532f2f5d
Author: Isaac Freund <ifreund@ifreund.xyz>
Date:   Sat, 26 Jun 2021 15:21:27 +0200

std/fmt: add fmtDurationSigned

When working with durations it often makes sense to use signed integers
and allow negative durations, and there is currently no nice way to
format these in std.fmt. This patch adds a simple wrapper for the
existing fmtDurtion to fit this need.

Diffstat:
Mlib/std/fmt.zig | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+), 0 deletions(-)

diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig @@ -1461,6 +1461,87 @@ test "fmtDuration" { } } +fn formatDurationSigned(ns: i64, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void { + if (ns < 0) { + try writer.writeByte('-'); + try formatDuration(@intCast(u64, -ns), fmt, options, writer); + } else { + try formatDuration(@intCast(u64, ns), fmt, options, writer); + } +} + +/// Return a Formatter for number of nanoseconds according to its signed magnitude: +/// [#y][#w][#d][#h][#m]#[.###][n|u|m]s +pub fn fmtDurationSigned(ns: i64) Formatter(formatDurationSigned) { + return .{ .data = ns }; +} + +test "fmtDurationSigned" { + var buf: [24]u8 = undefined; + inline for (.{ + .{ .s = "0ns", .d = 0 }, + .{ .s = "1ns", .d = 1 }, + .{ .s = "-1ns", .d = -(1) }, + .{ .s = "999ns", .d = std.time.ns_per_us - 1 }, + .{ .s = "-999ns", .d = -(std.time.ns_per_us - 1) }, + .{ .s = "1us", .d = std.time.ns_per_us }, + .{ .s = "-1us", .d = -(std.time.ns_per_us) }, + .{ .s = "1.45us", .d = 1450 }, + .{ .s = "-1.45us", .d = -(1450) }, + .{ .s = "1.5us", .d = 3 * std.time.ns_per_us / 2 }, + .{ .s = "-1.5us", .d = -(3 * std.time.ns_per_us / 2) }, + .{ .s = "14.5us", .d = 14500 }, + .{ .s = "-14.5us", .d = -(14500) }, + .{ .s = "145us", .d = 145000 }, + .{ .s = "-145us", .d = -(145000) }, + .{ .s = "999.999us", .d = std.time.ns_per_ms - 1 }, + .{ .s = "-999.999us", .d = -(std.time.ns_per_ms - 1) }, + .{ .s = "1ms", .d = std.time.ns_per_ms + 1 }, + .{ .s = "-1ms", .d = -(std.time.ns_per_ms + 1) }, + .{ .s = "1.5ms", .d = 3 * std.time.ns_per_ms / 2 }, + .{ .s = "-1.5ms", .d = -(3 * std.time.ns_per_ms / 2) }, + .{ .s = "1.11ms", .d = 1110000 }, + .{ .s = "-1.11ms", .d = -(1110000) }, + .{ .s = "1.111ms", .d = 1111000 }, + .{ .s = "-1.111ms", .d = -(1111000) }, + .{ .s = "1.111ms", .d = 1111100 }, + .{ .s = "-1.111ms", .d = -(1111100) }, + .{ .s = "999.999ms", .d = std.time.ns_per_s - 1 }, + .{ .s = "-999.999ms", .d = -(std.time.ns_per_s - 1) }, + .{ .s = "1s", .d = std.time.ns_per_s }, + .{ .s = "-1s", .d = -(std.time.ns_per_s) }, + .{ .s = "59.999s", .d = std.time.ns_per_min - 1 }, + .{ .s = "-59.999s", .d = -(std.time.ns_per_min - 1) }, + .{ .s = "1m", .d = std.time.ns_per_min }, + .{ .s = "-1m", .d = -(std.time.ns_per_min) }, + .{ .s = "1h", .d = std.time.ns_per_hour }, + .{ .s = "-1h", .d = -(std.time.ns_per_hour) }, + .{ .s = "1d", .d = std.time.ns_per_day }, + .{ .s = "-1d", .d = -(std.time.ns_per_day) }, + .{ .s = "1w", .d = std.time.ns_per_week }, + .{ .s = "-1w", .d = -(std.time.ns_per_week) }, + .{ .s = "1y", .d = 365 * std.time.ns_per_day }, + .{ .s = "-1y", .d = -(365 * std.time.ns_per_day) }, + .{ .s = "1y52w23h59m59.999s", .d = 730 * std.time.ns_per_day - 1 }, // 365d = 52w1d + .{ .s = "-1y52w23h59m59.999s", .d = -(730 * std.time.ns_per_day - 1) }, // 365d = 52w1d + .{ .s = "1y1h1.001s", .d = 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms }, + .{ .s = "-1y1h1.001s", .d = -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + std.time.ns_per_ms) }, + .{ .s = "1y1h1s", .d = 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us }, + .{ .s = "-1y1h1s", .d = -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_s + 999 * std.time.ns_per_us) }, + .{ .s = "1y1h999.999us", .d = 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1 }, + .{ .s = "-1y1h999.999us", .d = -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms - 1) }, + .{ .s = "1y1h1ms", .d = 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms }, + .{ .s = "-1y1h1ms", .d = -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms) }, + .{ .s = "1y1h1ms", .d = 365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1 }, + .{ .s = "-1y1h1ms", .d = -(365 * std.time.ns_per_day + std.time.ns_per_hour + std.time.ns_per_ms + 1) }, + .{ .s = "1y1m999ns", .d = 365 * std.time.ns_per_day + std.time.ns_per_min + 999 }, + .{ .s = "-1y1m999ns", .d = -(365 * std.time.ns_per_day + std.time.ns_per_min + 999) }, + }) |tc| { + const slice = try bufPrint(&buf, "{}", .{fmtDurationSigned(tc.d)}); + try std.testing.expectEqualStrings(tc.s, slice); + } +} + pub const ParseIntError = error{ /// The result cannot fit in the type specified Overflow,