diff --git a/src/Duration.zig b/src/Duration.zig index 821e49a..e16e521 100644 --- a/src/Duration.zig +++ b/src/Duration.zig @@ -177,14 +177,14 @@ pub fn toString(self: Duration, allocator: std.mem.Allocator, options: ToStringR var write = abi.DiplomatWrite.init(allocator); defer write.deinit(); - const res = abi.c.temporal_rs_Duration_to_string(self._inner, options, &write.inner); + const res = abi.c.temporal_rs_Duration_to_string(self._inner, options.toCApi(), &write.inner); try handleVoidResult(res); return try write.toOwnedSlice(); } pub fn toJSON(self: Duration, allocator: std.mem.Allocator) ![]u8 { - return self.toString(allocator, defaultToStringRoundingOptions()); + return self.toString(allocator, .{}); } pub fn toLocaleString(self: Duration, allocator: std.mem.Allocator) ![]u8 { @@ -214,26 +214,8 @@ fn wrapDuration(res: anytype) !Duration { return .{ ._inner = ptr }; } -fn defaultToStringRoundingOptions() ToStringRoundingOptions { - return abi.to_string_rounding_options_auto; -} - // --- Public helper types ----------------------------------------------------- -/// Options for Duration.toString() -/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toString -pub const ToStringOptions = struct { - /// Specifies the number of fractional seconds digits to display. - fractional_second_digits: ?u8 = null, - - /// Specifies how to round off fractional second digits. - /// Defaults to "trunc" (truncate). - rounding_mode: ?RoundingMode = null, - - /// Specifies the smallest unit to include in the output. - smallest_unit: ?Unit = null, -}; - pub const PartialDuration = abi.c.PartialDuration; /// Relative-to context for duration operations. @@ -253,7 +235,8 @@ const Unit_option = abi.c.Unit_option; const RoundingMode_option = abi.c.RoundingMode_option; pub const RoundingOptions = temporal.RoundingOptions; -pub const ToStringRoundingOptions = abi.c.ToStringRoundingOptions; +pub const ToStringOptions = temporal.ToStringRoundingOptions; +pub const ToStringRoundingOptions = temporal.ToStringRoundingOptions; pub const Unit = temporal.Unit; pub const RoundingMode = temporal.RoundingMode; pub const Sign = temporal.Sign; @@ -361,7 +344,7 @@ test toString { defer dur.deinit(); const allocator = std.testing.allocator; - const str = try dur.toString(allocator, defaultToStringRoundingOptions()); + const str = try dur.toString(allocator, .{}); defer allocator.free(str); // Should output ISO 8601 duration format diff --git a/src/Instant.zig b/src/Instant.zig index 3d07582..b58b31e 100644 --- a/src/Instant.zig +++ b/src/Instant.zig @@ -362,7 +362,7 @@ test until { .largest_unit = .hour, .smallest_unit = .second, .rounding_mode = .trunc, - .increment = null, + .rounding_increment = null, }; var until_handle = try earlier.until(later, settings); @@ -386,7 +386,7 @@ test since { .largest_unit = .hour, .smallest_unit = .second, .rounding_mode = .trunc, - .increment = null, + .rounding_increment = null, }; var until_handle = try earlier.until(later, settings); @@ -408,7 +408,7 @@ test round { .largest_unit = null, .smallest_unit = .second, .rounding_mode = .half_expand, - .increment = null, + .rounding_increment = null, }; const rounded = try inst.round(opts); diff --git a/src/temporal.zig b/src/temporal.zig index 38506b4..3761a80 100644 --- a/src/temporal.zig +++ b/src/temporal.zig @@ -95,35 +95,66 @@ pub const Sign = enum { }; /// Options for rounding operations (Instant.round, Duration.round, etc.). +/// MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/round pub const RoundingOptions = struct { largest_unit: ?Unit = null, smallest_unit: ?Unit = null, rounding_mode: ?RoundingMode = null, - increment: ?u32 = null, + rounding_increment: ?u32 = null, pub fn toCApi(self: RoundingOptions) c.RoundingOptions { return .{ .largest_unit = abi.toUnitOption(toCUnit(self.largest_unit)), .smallest_unit = abi.toUnitOption(toCUnit(self.smallest_unit)), .rounding_mode = abi.toRoundingModeOption(toCRoundingMode(self.rounding_mode)), - .increment = abi.toOption(c.OptionU32, self.increment), + .increment = abi.toOption(c.OptionU32, self.rounding_increment), }; } }; /// Options for computing differences between instants. +/// MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/until pub const DifferenceSettings = struct { largest_unit: ?Unit = null, smallest_unit: ?Unit = null, rounding_mode: ?RoundingMode = null, - increment: ?u32 = null, + rounding_increment: ?u32 = null, pub fn toCApi(self: DifferenceSettings) c.DifferenceSettings { return .{ .largest_unit = abi.toUnitOption(toCUnit(self.largest_unit)), .smallest_unit = abi.toUnitOption(toCUnit(self.smallest_unit)), .rounding_mode = abi.toRoundingModeOption(toCRoundingMode(self.rounding_mode)), - .increment = abi.toOption(c.OptionU32, self.increment), + .increment = abi.toOption(c.OptionU32, self.rounding_increment), + }; + } +}; + +/// Options for Duration.toString() formatting. +/// MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toString +pub const ToStringRoundingOptions = struct { + fractional_second_digits: ?u8 = null, + smallest_unit: ?Unit = null, + rounding_mode: ?RoundingMode = null, + + pub fn toCApi(self: ToStringRoundingOptions) c.ToStringRoundingOptions { + const precision: c.Precision = if (self.fractional_second_digits) |fsd| + .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, fsd) } + else if (self.smallest_unit) |su| + switch (su) { + .second => .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, 0) }, + .millisecond => .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, 3) }, + .microsecond => .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, 6) }, + .nanosecond => .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, 9) }, + else => .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, null) }, + } + else + .{ .is_minute = false, .precision = abi.toOption(c.OptionU8, null) }; + + return .{ + .precision = precision, + .smallest_unit = abi.toUnitOption(toCUnit(self.smallest_unit)), + .rounding_mode = abi.toRoundingModeOption(toCRoundingMode(self.rounding_mode)), }; } };