const abi = @import("abi.zig"); const c = abi.c; /// Time unit for Temporal operations. /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal pub const Unit = enum { auto, nanosecond, microsecond, millisecond, second, minute, hour, day, week, month, year, pub fn toCApi(self: Unit) c_uint { return switch (self) { .auto => c.Unit_Auto, .nanosecond => c.Unit_Nanosecond, .microsecond => c.Unit_Microsecond, .millisecond => c.Unit_Millisecond, .second => c.Unit_Second, .minute => c.Unit_Minute, .hour => c.Unit_Hour, .day => c.Unit_Day, .week => c.Unit_Week, .month => c.Unit_Month, .year => c.Unit_Year, }; } }; /// Rounding mode for Temporal operations. /// See: https://tc39.es/ecma402/#table-sanctioned-single-unit-identifiers pub const RoundingMode = enum { /// Round toward positive infinity ceil, /// Round toward negative infinity floor, /// Round away from zero expand, /// Round toward zero (truncate) trunc, /// Round half toward positive infinity half_ceil, /// Round half toward negative infinity half_floor, /// Round half away from zero half_expand, /// Round half toward zero half_trunc, /// Round half to even (banker's rounding) half_even, pub fn toCApi(self: RoundingMode) c_uint { return switch (self) { .ceil => c.RoundingMode_Ceil, .floor => c.RoundingMode_Floor, .expand => c.RoundingMode_Expand, .trunc => c.RoundingMode_Trunc, .half_ceil => c.RoundingMode_HalfCeil, .half_floor => c.RoundingMode_HalfFloor, .half_expand => c.RoundingMode_HalfExpand, .half_trunc => c.RoundingMode_HalfTrunc, .half_even => c.RoundingMode_HalfEven, }; } }; /// Sign of a duration or time value. pub const Sign = enum { positive, zero, negative, pub fn toCApi(self: Sign) c_int { return switch (self) { .positive => c.Sign_Positive, .zero => c.Sign_Zero, .negative => c.Sign_Negative, }; } pub fn fromCApi(value: c_int) Sign { return switch (value) { c.Sign_Positive => .positive, c.Sign_Zero => .zero, c.Sign_Negative => .negative, else => .zero, }; } }; /// 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, 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.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, 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.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)), }; } }; fn toCUnit(opt: ?Unit) ?c.Unit { return if (opt) |u| @as(c.Unit, @intCast(u.toCApi())) else null; } fn toCRoundingMode(opt: ?RoundingMode) ?c.RoundingMode { return if (opt) |m| @as(c.RoundingMode, @intCast(m.toCApi())) else null; }