refactor: abstract abi

This commit is contained in:
Nurul Huda (Apon) 2026-01-30 02:51:09 +06:00
parent 7f800d00b1
commit a54bcff837
10 changed files with 250 additions and 245 deletions

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal = @import("temporal.zig"); const t = @import("temporal.zig");
const PlainDate = @import("PlainDate.zig"); const PlainDate = @import("PlainDate.zig");
const PlainDateTime = @import("PlainDateTime.zig"); const PlainDateTime = @import("PlainDateTime.zig");
@ -8,11 +8,13 @@ const ZonedDateTime = @import("ZonedDateTime.zig");
const Duration = @This(); const Duration = @This();
pub const ToStringOptions = temporal.ToStringRoundingOptions; _inner: *abi.c.Duration,
pub const ToStringRoundingOptions = temporal.ToStringRoundingOptions;
pub const Unit = temporal.Unit; pub const ToStringOptions = t.ToStringRoundingOptions;
pub const RoundingMode = temporal.RoundingMode; pub const ToStringRoundingOptions = t.ToStringRoundingOptions;
pub const Sign = temporal.Sign; pub const Unit = t.Unit;
pub const RoundingMode = t.RoundingMode;
pub const Sign = t.Sign;
pub const RoundingOptions = struct { pub const RoundingOptions = struct {
largest_unit: ?Unit = null, largest_unit: ?Unit = null,
@ -20,15 +22,6 @@ pub const RoundingOptions = struct {
rounding_mode: ?RoundingMode = null, rounding_mode: ?RoundingMode = null,
rounding_increment: ?u32 = null, rounding_increment: ?u32 = null,
relative_to: ?RelativeTo = null, relative_to: ?RelativeTo = null,
pub fn toCApi(self: RoundingOptions) abi.c.RoundingOptions {
return .{
.largest_unit = abi.toUnitOption(temporal.toCUnit(self.largest_unit)),
.smallest_unit = abi.toUnitOption(temporal.toCUnit(self.smallest_unit)),
.rounding_mode = abi.toRoundingModeOption(temporal.toCRoundingMode(self.rounding_mode)),
.increment = abi.toOption(abi.c.OptionU32, self.rounding_increment),
};
}
}; };
/// Partial duration specification for creating Duration objects. /// Partial duration specification for creating Duration objects.
@ -44,31 +37,6 @@ pub const PartialDuration = struct {
milliseconds: ?i64 = null, milliseconds: ?i64 = null,
microseconds: ?f64 = null, microseconds: ?f64 = null,
nanoseconds: ?f64 = null, nanoseconds: ?f64 = null,
fn toCApi(self: PartialDuration) abi.c.PartialDuration {
return .{
.years = abi.toOption(abi.c.OptionI64, self.years),
.months = abi.toOption(abi.c.OptionI64, self.months),
.weeks = abi.toOption(abi.c.OptionI64, self.weeks),
.days = abi.toOption(abi.c.OptionI64, self.days),
.hours = abi.toOption(abi.c.OptionI64, self.hours),
.minutes = abi.toOption(abi.c.OptionI64, self.minutes),
.seconds = abi.toOption(abi.c.OptionI64, self.seconds),
.milliseconds = abi.toOption(abi.c.OptionI64, self.milliseconds),
.microseconds = abi.toOption(abi.c.OptionF64, self.microseconds),
.nanoseconds = abi.toOption(abi.c.OptionF64, self.nanoseconds),
};
}
};
/// Wrapper for PlainDate reference in RelativeTo
const PlainDateRef = struct {
_inner: *abi.c.PlainDate,
};
/// Wrapper for ZonedDateTime reference in RelativeTo
const ZonedDateTimeRef = struct {
_inner: *abi.c.ZonedDateTime,
}; };
/// Relative-to context for duration operations. /// Relative-to context for duration operations.
@ -76,14 +44,6 @@ pub const RelativeTo = union(enum) {
plain_date: PlainDate, plain_date: PlainDate,
plain_date_time: PlainDateTime, plain_date_time: PlainDateTime,
zoned_date_time: ZonedDateTime, zoned_date_time: ZonedDateTime,
fn toCApi(self: RelativeTo) abi.c.RelativeTo {
switch (self) {
.plain_date => |pd| return .{ .date = pd._inner },
.zoned_date_time => |zdt| return .{ .zoned = zdt._inner },
.plain_date_time => |pdt| return .{ .date = (pdt.toPlainDate() catch unreachable)._inner },
}
}
}; };
/// Options for Duration.total() providing unit and relative-to context. /// Options for Duration.total() providing unit and relative-to context.
@ -96,8 +56,6 @@ pub const CompareOptions = struct {
relative_to: ?RelativeTo = null, relative_to: ?RelativeTo = null,
}; };
_inner: *abi.c.Duration,
/// Construct a Duration from years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds. /// Construct a Duration from years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds.
/// Equivalent to `Temporal.Duration.from()` or the constructor. /// Equivalent to `Temporal.Duration.from()` or the constructor.
pub fn init( pub fn init(
@ -176,7 +134,7 @@ inline fn fromUtf8(text: []const u8) !Duration {
/// Create a Duration from a partial duration (where some fields may be omitted). /// Create a Duration from a partial duration (where some fields may be omitted).
fn fromPartialDuration(partial: PartialDuration) !Duration { fn fromPartialDuration(partial: PartialDuration) !Duration {
return wrapDuration(abi.c.temporal_rs_Duration_from_partial_duration(partial.toCApi())); return wrapDuration(abi.c.temporal_rs_Duration_from_partial_duration(abi.to.partialdur(partial)));
} }
/// Check if the time portion of the duration is within valid ranges. /// Check if the time portion of the duration is within valid ranges.
@ -236,7 +194,7 @@ pub fn nanoseconds(self: Duration) f64 {
/// Get the sign of the duration: positive (1), zero (0), or negative (-1). /// Get the sign of the duration: positive (1), zero (0), or negative (-1).
pub fn sign(self: Duration) Sign { pub fn sign(self: Duration) Sign {
return Sign.fromCApi(abi.c.temporal_rs_Duration_sign(self._inner)); return abi.from.sign(abi.c.temporal_rs_Duration_sign(self._inner));
} }
/// Check if the duration is zero (all fields are zero). /// Check if the duration is zero (all fields are zero).
@ -268,8 +226,8 @@ pub fn subtract(self: Duration, other: Duration) !Duration {
/// Round the duration according to the specified options (Temporal.Duration.prototype.round). /// Round the duration according to the specified options (Temporal.Duration.prototype.round).
pub fn round(self: Duration, options: RoundingOptions) !Duration { pub fn round(self: Duration, options: RoundingOptions) !Duration {
const rel = if (options.relative_to) |r| r.toCApi() else abi.c.RelativeTo{ .date = null, .zoned = null }; const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
return wrapDuration(abi.c.temporal_rs_Duration_round(self._inner, options.toCApi(), rel)); return wrapDuration(abi.c.temporal_rs_Duration_round(self._inner, abi.to.durRoundingOpts(options), rel));
} }
/// Round the duration with an explicit provider. /// Round the duration with an explicit provider.
@ -279,7 +237,7 @@ fn roundWithProvider(self: Duration, options: RoundingOptions, relative_to: Rela
/// Compare two durations (Temporal.Duration.compare). /// Compare two durations (Temporal.Duration.compare).
pub fn compare(self: Duration, other: Duration, options: CompareOptions) !i8 { pub fn compare(self: Duration, other: Duration, options: CompareOptions) !i8 {
const rel = if (options.relative_to) |r| r.toCApi() else abi.c.RelativeTo{ .date = null, .zoned = null }; const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
const res = abi.c.temporal_rs_Duration_compare(self._inner, other._inner, rel); const res = abi.c.temporal_rs_Duration_compare(self._inner, other._inner, rel);
return try abi.extractResult(res); return try abi.extractResult(res);
} }
@ -292,14 +250,14 @@ fn compareWithProvider(self: Duration, other: Duration, relative_to: RelativeTo,
/// Get the total value of the duration in the specified unit (Temporal.Duration.prototype.total). /// Get the total value of the duration in the specified unit (Temporal.Duration.prototype.total).
pub fn total(self: Duration, options: TotalOptions) !f64 { pub fn total(self: Duration, options: TotalOptions) !f64 {
const rel = if (options.relative_to) |r| r.toCApi() else abi.c.RelativeTo{ .date = null, .zoned = null }; const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
const res = abi.c.temporal_rs_Duration_total(self._inner, options.unit.toCApi(), rel); const res = abi.c.temporal_rs_Duration_total(self._inner, abi.to.unit(options.unit).?, rel);
return try abi.extractResult(res); return try abi.extractResult(res);
} }
/// Get the total value of the duration with an explicit provider. /// Get the total value of the duration with an explicit provider.
fn totalWithProvider(self: Duration, options: TotalOptions, provider: *const abi.c.Provider) !f64 { fn totalWithProvider(self: Duration, options: TotalOptions, provider: *const abi.c.Provider) !f64 {
const rel = if (options.relative_to) |r| r.toCApi() else abi.c.RelativeTo{ .date = null, .zoned = null }; const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
const res = abi.c.temporal_rs_Duration_total_with_provider(self._inner, options.unit.toCApi(), rel, provider); const res = abi.c.temporal_rs_Duration_total_with_provider(self._inner, options.unit.toCApi(), rel, provider);
return try abi.extractResult(res); return try abi.extractResult(res);
} }
@ -309,7 +267,7 @@ pub fn toString(self: Duration, allocator: std.mem.Allocator, options: ToStringR
var write = abi.DiplomatWrite.init(allocator); var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); defer write.deinit();
const res = abi.c.temporal_rs_Duration_to_string(self._inner, options.toCApi(), &write.inner); const res = abi.c.temporal_rs_Duration_to_string(self._inner, abi.to.strRoundingOpts(options), &write.inner);
try handleVoidResult(res); try handleVoidResult(res);
return try write.toOwnedSlice(); return try write.toOwnedSlice();
@ -580,15 +538,15 @@ test total {
const dur = try Duration.init(0, 0, 0, 0, 1, 30, 0, 0, 0, 0); const dur = try Duration.init(0, 0, 0, 0, 1, 30, 0, 0, 0, 0);
defer dur.deinit(); defer dur.deinit();
const t = try dur.total(.{ .unit = .hour }); const ttl = try dur.total(.{ .unit = .hour });
try std.testing.expectEqual(1.5, t); try std.testing.expectEqual(1.5, ttl);
} }
{ {
const dur = try Duration.from("PT4H5M6S"); const dur = try Duration.from("PT4H5M6S");
defer dur.deinit(); defer dur.deinit();
const t = try dur.total(.{ .unit = .hour }); const ttl = try dur.total(.{ .unit = .hour });
try std.testing.expectEqual(4.085, t); try std.testing.expectEqual(4.085, ttl);
} }
{ {

View file

@ -1,30 +1,19 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal = @import("temporal.zig"); const t = @import("temporal.zig");
const Duration = @import("Duration.zig"); const Duration = @import("Duration.zig");
const Instant = @This(); const Instant = @This();
pub const Unit = temporal.Unit; _inner: *abi.c.Instant,
pub const RoundingMode = temporal.RoundingMode;
pub const Sign = temporal.Sign;
pub const RoundingOptions = temporal.RoundingOptions;
pub const DifferenceSettings = temporal.DifferenceSettings;
/// Time zone identifier for Temporal operations pub const Unit = t.Unit;
pub const TimeZone = struct { pub const RoundingMode = t.RoundingMode;
_inner: abi.c.TimeZone, pub const Sign = t.Sign;
pub const RoundingOptions = t.RoundingOptions;
pub fn init(id: []const u8) TimeZone { pub const DifferenceSettings = t.DifferenceSettings;
const view = abi.toDiplomatStringView(id); pub const TimeZone = t.TimeZone;
return .{ ._inner = .{ .id = view } };
}
fn toCApi(self: TimeZone) abi.c.TimeZone {
return self._inner;
}
};
/// Options for Instant.toString() /// Options for Instant.toString()
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString
@ -47,8 +36,6 @@ pub const ToStringOptions = struct {
time_zone: ?TimeZone = null, time_zone: ?TimeZone = null,
}; };
_inner: *abi.c.Instant,
/// Construct from epoch nanoseconds (Temporal.Instant.fromEpochNanoseconds). /// Construct from epoch nanoseconds (Temporal.Instant.fromEpochNanoseconds).
pub fn init(epoch_ns: i128) !Instant { pub fn init(epoch_ns: i128) !Instant {
return fromEpochNanoseconds(epoch_ns); return fromEpochNanoseconds(epoch_ns);
@ -112,19 +99,19 @@ pub fn subtract(self: Instant, duration: *Duration) !Instant {
/// Difference until another instant (Temporal.Instant.prototype.until). /// Difference until another instant (Temporal.Instant.prototype.until).
pub fn until(self: Instant, other: Instant, settings: DifferenceSettings) !Duration { pub fn until(self: Instant, other: Instant, settings: DifferenceSettings) !Duration {
const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_until(self._inner, other._inner, settings.toCApi()))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_until(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
/// Difference since another instant (Temporal.Instant.prototype.since). /// Difference since another instant (Temporal.Instant.prototype.since).
pub fn since(self: Instant, other: Instant, settings: DifferenceSettings) !Duration { pub fn since(self: Instant, other: Instant, settings: DifferenceSettings) !Duration {
const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_since(self._inner, other._inner, settings.toCApi()))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_since(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
/// Round this instant (Temporal.Instant.prototype.round). /// Round this instant (Temporal.Instant.prototype.round).
pub fn round(self: Instant, options: RoundingOptions) !Instant { pub fn round(self: Instant, options: RoundingOptions) !Instant {
return wrapInstant(abi.c.temporal_rs_Instant_round(self._inner, options.toCApi())); return wrapInstant(abi.c.temporal_rs_Instant_round(self._inner, abi.to.roundingOpts(options)));
} }
/// Compare two instants (Temporal.Instant.compare). /// Compare two instants (Temporal.Instant.compare).
@ -235,8 +222,8 @@ fn optsToRounding(opts: ToStringOptions) abi.c.ToStringRoundingOptions {
else else
defaultPrecision(); defaultPrecision();
const smallest_unit = if (opts.smallest_unit) |unit| unit.toCApi() else null; const smallest_unit = if (opts.smallest_unit) |unit| abi.to.unit(unit).? else null;
const rounding_mode = if (opts.rounding_mode) |mode| mode.toCApi() else null; const rounding_mode = if (opts.rounding_mode) |mode| abi.to.roundingMode(mode) else null;
return .{ return .{
.precision = precision, .precision = precision,

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal = @import("temporal.zig"); const t = @import("temporal.zig");
const PlainDateTime = @import("PlainDateTime.zig"); const PlainDateTime = @import("PlainDateTime.zig");
const PlainMonthDay = @import("PlainMonthDay.zig"); const PlainMonthDay = @import("PlainMonthDay.zig");
@ -11,10 +11,12 @@ const Duration = @import("Duration.zig");
const PlainDate = @This(); const PlainDate = @This();
pub const Unit = temporal.Unit; _inner: *abi.c.PlainDate,
pub const RoundingMode = temporal.RoundingMode;
pub const Sign = temporal.Sign; pub const Unit = t.Unit;
pub const DifferenceSettings = temporal.DifferenceSettings; pub const RoundingMode = t.RoundingMode;
pub const Sign = t.Sign;
pub const DifferenceSettings = t.DifferenceSettings;
pub const ToStringOptions = struct { pub const ToStringOptions = struct {
calendar_id: ?CalendarDisplay = null, calendar_id: ?CalendarDisplay = null,
@ -41,8 +43,6 @@ pub const ToZonedDateTimeOptions = struct {
plain_time: ?PlainTime = null, plain_time: ?PlainTime = null,
}; };
_inner: *abi.c.PlainDate,
pub fn init(year_val: i32, month_val: u8, day_val: u8) !PlainDate { pub fn init(year_val: i32, month_val: u8, day_val: u8) !PlainDate {
return calInit(year_val, month_val, day_val, "iso8601"); return calInit(year_val, month_val, day_val, "iso8601");
} }
@ -104,12 +104,12 @@ pub fn subtract(self: PlainDate, duration: Duration) !PlainDate {
} }
pub fn until(self: PlainDate, other: PlainDate, settings: DifferenceSettings) !Duration { pub fn until(self: PlainDate, other: PlainDate, settings: DifferenceSettings) !Duration {
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_until(self._inner, other._inner, settings.toCApi()))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_until(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
pub fn since(self: PlainDate, other: PlainDate, settings: DifferenceSettings) !Duration { pub fn since(self: PlainDate, other: PlainDate, settings: DifferenceSettings) !Duration {
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_since(self._inner, other._inner, settings.toCApi()))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_since(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
@ -129,7 +129,7 @@ pub fn withCalendar(self: PlainDate, calendar: []const u8) !PlainDate {
} }
pub fn toPlainDateTime(self: PlainDate, time: ?PlainTime) !PlainDateTime { pub fn toPlainDateTime(self: PlainDate, time: ?PlainTime) !PlainDateTime {
const time_ptr = if (time) |t| t._inner else null; const time_ptr = if (time) |tt| tt._inner else null;
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_to_plain_date_time(self._inner, time_ptr))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_to_plain_date_time(self._inner, time_ptr))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
@ -149,7 +149,7 @@ pub fn toZonedDateTime(self: PlainDate, options: ToZonedDateTimeOptions) !ZonedD
const tz_result = abi.c.temporal_rs_TimeZone_try_from_str(tz_view); const tz_result = abi.c.temporal_rs_TimeZone_try_from_str(tz_view);
const time_zone = try abi.extractResult(tz_result); const time_zone = try abi.extractResult(tz_result);
const time_ptr = if (options.plain_time) |t| t._inner else null; const time_ptr = if (options.plain_time) |tt| tt._inner else null;
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_to_zoned_date_time(self._inner, time_zone, time_ptr))) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_to_zoned_date_time(self._inner, time_zone, time_ptr))) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal = @import("temporal.zig"); const t = @import("temporal.zig");
const PlainDate = @import("PlainDate.zig"); const PlainDate = @import("PlainDate.zig");
const PlainTime = @import("PlainTime.zig"); const PlainTime = @import("PlainTime.zig");
@ -12,11 +12,11 @@ const PlainDateTime = @This();
_inner: *abi.c.PlainDateTime, _inner: *abi.c.PlainDateTime,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal.Unit; pub const Unit = t.Unit;
pub const RoundingMode = temporal.RoundingMode; pub const RoundingMode = t.RoundingMode;
pub const Sign = temporal.Sign; pub const Sign = t.Sign;
pub const DifferenceSettings = temporal.DifferenceSettings; pub const DifferenceSettings = t.DifferenceSettings;
pub const RoundOptions = temporal.RoundingOptions; pub const RoundOptions = t.RoundingOptions;
// Type definitions for API compatibility // Type definitions for API compatibility
pub const CalendarDisplay = enum { pub const CalendarDisplay = enum {
auto, auto,
@ -208,20 +208,20 @@ pub fn subtract(self: PlainDateTime, duration: Duration) !PlainDateTime {
} }
pub fn until(self: PlainDateTime, other: PlainDateTime, options: DifferenceSettings) !Duration { pub fn until(self: PlainDateTime, other: PlainDateTime, options: DifferenceSettings) !Duration {
const result = abi.c.temporal_rs_PlainDateTime_until(self._inner, other._inner, options.toCApi()); const result = abi.c.temporal_rs_PlainDateTime_until(self._inner, other._inner, abi.to.diffsettings(options));
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
pub fn since(self: PlainDateTime, other: PlainDateTime, options: DifferenceSettings) !Duration { pub fn since(self: PlainDateTime, other: PlainDateTime, options: DifferenceSettings) !Duration {
const result = abi.c.temporal_rs_PlainDateTime_since(self._inner, other._inner, options.toCApi()); const result = abi.c.temporal_rs_PlainDateTime_since(self._inner, other._inner, abi.to.diffsettings(options));
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
// Rounding // Rounding
pub fn round(self: PlainDateTime, options: RoundOptions) !PlainDateTime { pub fn round(self: PlainDateTime, options: RoundOptions) !PlainDateTime {
return wrapPlainDateTime(abi.c.temporal_rs_PlainDateTime_round(self._inner, options.toCApi())); return wrapPlainDateTime(abi.c.temporal_rs_PlainDateTime_round(self._inner, abi.to.roundingOpts(options)));
} }
// Property accessors - Date fields // Property accessors - Date fields
@ -375,12 +375,12 @@ pub fn withCalendar(self: PlainDateTime, calendar: []const u8) !PlainDateTime {
} }
pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime { pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime {
const new_hour: u8 = if (time) |t| t.hour() else 0; const new_hour: u8 = if (time) |tt| tt.hour() else 0;
const new_minute: u8 = if (time) |t| t.minute() else 0; const new_minute: u8 = if (time) |tt| tt.minute() else 0;
const new_second: u8 = if (time) |t| t.second() else 0; const new_second: u8 = if (time) |tt| tt.second() else 0;
const new_millisecond: u16 = if (time) |t| t.millisecond() else 0; const new_millisecond: u16 = if (time) |tt| tt.millisecond() else 0;
const new_microsecond: u16 = if (time) |t| t.microsecond() else 0; const new_microsecond: u16 = if (time) |tt| tt.microsecond() else 0;
const new_nanosecond: u16 = if (time) |t| t.nanosecond() else 0; const new_nanosecond: u16 = if (time) |tt| tt.nanosecond() else 0;
const calendar_ptr = abi.c.temporal_rs_PlainDateTime_calendar(self._inner) orelse return error.TemporalError; const calendar_ptr = abi.c.temporal_rs_PlainDateTime_calendar(self._inner) orelse return error.TemporalError;
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr); const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
@ -597,10 +597,10 @@ test toPlainDate {
test toPlainTime { test toPlainTime {
const dt = try PlainDateTime.init(2024, 1, 15, 14, 30, 45, 0, 0, 0); const dt = try PlainDateTime.init(2024, 1, 15, 14, 30, 45, 0, 0, 0);
const t = try dt.toPlainTime(); const tt = try dt.toPlainTime();
try std.testing.expectEqual(@as(u8, 14), t.hour()); try std.testing.expectEqual(@as(u8, 14), tt.hour());
try std.testing.expectEqual(@as(u8, 30), t.minute()); try std.testing.expectEqual(@as(u8, 30), tt.minute());
try std.testing.expectEqual(@as(u8, 45), t.second()); try std.testing.expectEqual(@as(u8, 45), tt.second());
} }
test toZonedDateTime { test toZonedDateTime {
@ -635,8 +635,8 @@ test withCalendar {
test withPlainTime { test withPlainTime {
const dt = try PlainDateTime.init(2024, 1, 15, 14, 30, 0, 0, 0, 0); const dt = try PlainDateTime.init(2024, 1, 15, 14, 30, 0, 0, 0, 0);
const t = try PlainTime.from("10:15:30"); const tt = try PlainTime.from("10:15:30");
const result = try dt.withPlainTime(t); const result = try dt.withPlainTime(tt);
try std.testing.expectEqual(@as(u8, 10), result.hour()); try std.testing.expectEqual(@as(u8, 10), result.hour());
try std.testing.expectEqual(@as(u8, 15), result.minute()); try std.testing.expectEqual(@as(u8, 15), result.minute());
try std.testing.expectEqual(@as(u8, 30), result.second()); try std.testing.expectEqual(@as(u8, 30), result.second());

View file

@ -1,9 +1,10 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal_types = @import("temporal.zig"); const t = @import("temporal.zig");
const PlainDate = @import("PlainDate.zig");
const PlainMonthDay = @This(); const PlainMonthDay = @This();
const PlainDate = @import("PlainDate.zig");
_inner: *abi.c.PlainMonthDay, _inner: *abi.c.PlainMonthDay,

View file

@ -1,17 +1,18 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal_types = @import("temporal.zig"); const t = @import("temporal.zig");
const Duration = @import("Duration.zig");
const PlainTime = @This(); const PlainTime = @This();
const Duration = @import("Duration.zig");
_inner: *abi.c.PlainTime, _inner: *abi.c.PlainTime,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal_types.Unit; pub const Unit = t.Unit;
pub const RoundingMode = temporal_types.RoundingMode; pub const RoundingMode = t.RoundingMode;
pub const DifferenceSettings = temporal_types.DifferenceSettings; pub const DifferenceSettings = t.DifferenceSettings;
pub const RoundOptions = temporal_types.RoundingOptions; pub const RoundOptions = t.RoundingOptions;
pub const WithOptions = struct { pub const WithOptions = struct {
hour: ?u8 = null, hour: ?u8 = null,
@ -81,14 +82,14 @@ pub fn subtract(self: PlainTime, duration: Duration) !PlainTime {
} }
pub fn until(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration { pub fn until(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration {
const settings = options.toCApi(); const settings = abi.to.diffsettings(options);
const result = abi.c.temporal_rs_PlainTime_until(self._inner, other._inner, settings); const result = abi.c.temporal_rs_PlainTime_until(self._inner, other._inner, settings);
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
pub fn since(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration { pub fn since(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration {
const settings = options.toCApi(); const settings = abi.to.diffsettings(options);
const result = abi.c.temporal_rs_PlainTime_since(self._inner, other._inner, settings); const result = abi.c.temporal_rs_PlainTime_since(self._inner, other._inner, settings);
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
@ -96,7 +97,7 @@ pub fn since(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Du
// Rounding // Rounding
pub fn round(self: PlainTime, options: RoundOptions) !PlainTime { pub fn round(self: PlainTime, options: RoundOptions) !PlainTime {
return wrapPlainTime(abi.c.temporal_rs_PlainTime_round(self._inner, options.toCApi())); return wrapPlainTime(abi.c.temporal_rs_PlainTime_round(self._inner, abi.to.roundingOpts(options)));
} }
// Property accessors // Property accessors
@ -146,8 +147,8 @@ pub fn toString(self: PlainTime, allocator: std.mem.Allocator) ![]u8 {
return toStringWithOptions(self, allocator, .{}); return toStringWithOptions(self, allocator, .{});
} }
fn toStringWithOptions(self: PlainTime, allocator: std.mem.Allocator, options: temporal_types.ToStringRoundingOptions) ![]u8 { fn toStringWithOptions(self: PlainTime, allocator: std.mem.Allocator, options: t.ToStringRoundingOptions) ![]u8 {
const rounding_opts = options.toCApi(); const rounding_opts = abi.to.strRoundingOpts(options);
var write = abi.DiplomatWrite.init(allocator); var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); defer write.deinit();

View file

@ -1,18 +1,19 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal_types = @import("temporal.zig"); const t = @import("temporal.zig");
const PlainYearMonth = @This();
const PlainDate = @import("PlainDate.zig"); const PlainDate = @import("PlainDate.zig");
const Duration = @import("Duration.zig"); const Duration = @import("Duration.zig");
const PlainYearMonth = @This();
_inner: *abi.c.PlainYearMonth, _inner: *abi.c.PlainYearMonth,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal_types.Unit; pub const Unit = t.Unit;
pub const RoundingMode = temporal_types.RoundingMode; pub const RoundingMode = t.RoundingMode;
pub const DifferenceSettings = temporal_types.DifferenceSettings; pub const DifferenceSettings = t.DifferenceSettings;
pub const RoundOptions = temporal_types.RoundingOptions; pub const RoundOptions = t.RoundingOptions;
// Type definitions for API compatibility // Type definitions for API compatibility
pub const CalendarDisplay = enum { pub const CalendarDisplay = enum {
@ -95,14 +96,14 @@ pub fn subtract(self: PlainYearMonth, duration: Duration) !PlainYearMonth {
} }
pub fn until(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration { pub fn until(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration {
const settings = options.toCApi(); const settings = abi.to.diffsettings(options);
const result = abi.c.temporal_rs_PlainYearMonth_until(self._inner, other._inner, settings); const result = abi.c.temporal_rs_PlainYearMonth_until(self._inner, other._inner, settings);
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
pub fn since(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration { pub fn since(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration {
const settings = options.toCApi(); const settings = abi.to.diffsettings(options);
const result = abi.c.temporal_rs_PlainYearMonth_since(self._inner, other._inner, settings); const result = abi.c.temporal_rs_PlainYearMonth_since(self._inner, other._inner, settings);
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic; const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
return .{ ._inner = ptr }; return .{ ._inner = ptr };

View file

@ -1,6 +1,6 @@
const std = @import("std"); const std = @import("std");
const abi = @import("abi.zig"); const abi = @import("abi.zig");
const temporal_types = @import("temporal.zig"); const t = @import("temporal.zig");
const Instant = @import("Instant.zig"); const Instant = @import("Instant.zig");
const PlainDate = @import("PlainDate.zig"); const PlainDate = @import("PlainDate.zig");
@ -13,11 +13,11 @@ const ZonedDateTime = @This();
_inner: *abi.c.ZonedDateTime, _inner: *abi.c.ZonedDateTime,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal_types.Unit; pub const Unit = t.Unit;
pub const RoundingMode = temporal_types.RoundingMode; pub const RoundingMode = t.RoundingMode;
pub const Sign = temporal_types.Sign; pub const Sign = t.Sign;
pub const DifferenceSettings = temporal_types.DifferenceSettings; pub const DifferenceSettings = t.DifferenceSettings;
pub const RoundOptions = temporal_types.RoundingOptions; pub const RoundOptions = t.RoundingOptions;
pub const TimeZone = struct { pub const TimeZone = struct {
_inner: abi.c.TimeZone, _inner: abi.c.TimeZone,
@ -179,12 +179,12 @@ pub fn getTimeZoneTransition(self: ZonedDateTime, direction: enum { next, previo
/// Round to the given options /// Round to the given options
pub fn round(self: ZonedDateTime, options: RoundOptions) !ZonedDateTime { pub fn round(self: ZonedDateTime, options: RoundOptions) !ZonedDateTime {
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_round(self._inner, options.toCApi())); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_round(self._inner, abi.to.roundingOpts(options)));
} }
/// Calculate duration since another ZonedDateTime /// Calculate duration since another ZonedDateTime
pub fn since(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration { pub fn since(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration {
const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_since(self._inner, other._inner, settings.toCApi())); const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_since(self._inner, other._inner, abi.to.diffsettings(settings)));
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
@ -253,7 +253,7 @@ pub fn toString(self: ZonedDateTime, allocator: std.mem.Allocator, opts: ToStrin
/// Calculate duration until another ZonedDateTime /// Calculate duration until another ZonedDateTime
pub fn until(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration { pub fn until(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration {
const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_until(self._inner, other._inner, settings.toCApi())); const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_until(self._inner, other._inner, abi.to.diffsettings(settings)));
return .{ ._inner = ptr }; return .{ ._inner = ptr };
} }
@ -281,7 +281,7 @@ pub fn withCalendar(self: ZonedDateTime, calendar: []const u8) !ZonedDateTime {
/// Create a new ZonedDateTime with a different time /// Create a new ZonedDateTime with a different time
pub fn withPlainTime(self: ZonedDateTime, time: ?PlainTime) !ZonedDateTime { pub fn withPlainTime(self: ZonedDateTime, time: ?PlainTime) !ZonedDateTime {
const time_ptr = if (time) |t| t._inner else null; const time_ptr = if (time) |tt| tt._inner else null;
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_plain_time(self._inner, time_ptr)); return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_plain_time(self._inner, time_ptr));
} }

View file

@ -304,3 +304,145 @@ pub inline fn extractResult(result: anytype) TemporalError!Success(@TypeOf(resul
// Fallback for result types without detailed error information // Fallback for result types without detailed error information
return TemporalError.Generic; return TemporalError.Generic;
} }
const t = @import("temporal.zig");
const dur = @import("Duration.zig");
const ins = @import("Instant.zig");
pub const to = struct {
pub fn unit(opt: ?t.Unit) ?c.Unit {
return if (opt) |u| @as(c.Unit, @intCast(to.unitToCApi(u))) else null;
}
fn unitToCApi(u: t.Unit) c_uint {
return switch (u) {
.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,
};
}
pub fn roundingMode(opt: ?t.RoundingMode) ?c.RoundingMode {
return if (opt) |m| @as(c.RoundingMode, @intCast(to.roundingModeToCApi(m))) else null;
}
fn roundingModeToCApi(m: t.RoundingMode) c_uint {
return switch (m) {
.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,
};
}
pub fn sign(opt: ?t.Sign) ?c.Sign {
return if (opt) |s| @as(c.Sign, @intCast(to.signToCApi(s))) else null;
}
fn signToCApi(s: t.Sign) c_int {
return switch (s) {
.positive => c.Sign_Positive,
.zero => c.Sign_Zero,
.negative => c.Sign_Negative,
};
}
pub fn strRoundingOpts(self: t.ToStringRoundingOptions) c.ToStringRoundingOptions {
const precision: c.Precision = if (self.fractional_second_digits) |fsd|
.{ .is_minute = false, .precision = toOption(c.OptionU8, fsd) }
else if (self.smallest_unit) |su|
switch (su) {
.second => .{ .is_minute = false, .precision = toOption(c.OptionU8, 0) },
.millisecond => .{ .is_minute = false, .precision = toOption(c.OptionU8, 3) },
.microsecond => .{ .is_minute = false, .precision = toOption(c.OptionU8, 6) },
.nanosecond => .{ .is_minute = false, .precision = toOption(c.OptionU8, 9) },
else => .{ .is_minute = false, .precision = toOption(c.OptionU8, null) },
}
else
.{ .is_minute = false, .precision = toOption(c.OptionU8, null) };
return .{
.precision = precision,
.smallest_unit = toUnitOption(unit(self.smallest_unit)),
.rounding_mode = toRoundingModeOption(roundingMode(self.rounding_mode)),
};
}
pub fn durRoundingOpts(self: dur.RoundingOptions) c.RoundingOptions {
return .{
.largest_unit = toUnitOption(unit(self.largest_unit)),
.smallest_unit = toUnitOption(unit(self.smallest_unit)),
.rounding_mode = toRoundingModeOption(roundingMode(self.rounding_mode)),
.increment = toOption(c.OptionU32, self.rounding_increment),
};
}
pub fn tz(self: ins.TimeZone) c.TimeZone {
return self._inner;
}
pub fn partialdur(self: dur.PartialDuration) c.PartialDuration {
return .{
.years = toOption(c.OptionI64, self.years),
.months = toOption(c.OptionI64, self.months),
.weeks = toOption(c.OptionI64, self.weeks),
.days = toOption(c.OptionI64, self.days),
.hours = toOption(c.OptionI64, self.hours),
.minutes = toOption(c.OptionI64, self.minutes),
.seconds = toOption(c.OptionI64, self.seconds),
.milliseconds = toOption(c.OptionI64, self.milliseconds),
.microseconds = toOption(c.OptionF64, self.microseconds),
.nanoseconds = toOption(c.OptionF64, self.nanoseconds),
};
}
pub fn durRelativeTo(self: dur.RelativeTo) c.RelativeTo {
switch (self) {
.plain_date => |pd| return .{ .date = pd._inner },
.zoned_date_time => |zdt| return .{ .zoned = zdt._inner },
.plain_date_time => |pdt| return .{ .date = (pdt.toPlainDate() catch unreachable)._inner },
}
}
pub fn roundingOpts(self: t.RoundingOptions) c.RoundingOptions {
return .{
.largest_unit = toUnitOption(to.unit(self.largest_unit)),
.smallest_unit = toUnitOption(to.unit(self.smallest_unit)),
.rounding_mode = toRoundingModeOption(to.roundingMode(self.rounding_mode)),
.increment = toOption(c.OptionU32, self.rounding_increment),
};
}
pub fn diffsettings(self: t.DifferenceSettings) c.DifferenceSettings {
return .{
.largest_unit = toUnitOption(to.unit(self.largest_unit)),
.smallest_unit = toUnitOption(to.unit(self.smallest_unit)),
.rounding_mode = toRoundingModeOption(to.roundingMode(self.rounding_mode)),
.increment = toOption(c.OptionU32, self.rounding_increment),
};
}
};
pub const from = struct {
pub fn sign(value: c_int) t.Sign {
return switch (value) {
c.Sign_Positive => .positive,
c.Sign_Zero => .zero,
c.Sign_Negative => .negative,
else => .zero,
};
}
};

View file

@ -1,6 +1,3 @@
const abi = @import("abi.zig");
const c = abi.c;
/// Time unit for Temporal operations. /// Time unit for Temporal operations.
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal /// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal
pub const Unit = enum { pub const Unit = enum {
@ -15,22 +12,6 @@ pub const Unit = enum {
week, week,
month, month,
year, 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. /// Rounding mode for Temporal operations.
@ -54,20 +35,6 @@ pub const RoundingMode = enum {
half_trunc, half_trunc,
/// Round half to even (banker's rounding) /// Round half to even (banker's rounding)
half_even, 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. /// Sign of a duration or time value.
@ -75,23 +42,6 @@ pub const Sign = enum {
positive, positive,
zero, zero,
negative, 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.). /// Options for rounding operations (Instant.round, Duration.round, etc.).
@ -101,15 +51,6 @@ pub const RoundingOptions = struct {
smallest_unit: ?Unit = null, smallest_unit: ?Unit = null,
rounding_mode: ?RoundingMode = null, rounding_mode: ?RoundingMode = null,
rounding_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.rounding_increment),
};
}
}; };
/// Options for computing differences between instants. /// Options for computing differences between instants.
@ -119,15 +60,6 @@ pub const DifferenceSettings = struct {
smallest_unit: ?Unit = null, smallest_unit: ?Unit = null,
rounding_mode: ?RoundingMode = null, rounding_mode: ?RoundingMode = null,
rounding_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.rounding_increment),
};
}
}; };
/// Options for Duration.toString() formatting. /// Options for Duration.toString() formatting.
@ -136,33 +68,16 @@ pub const ToStringRoundingOptions = struct {
fractional_second_digits: ?u8 = null, fractional_second_digits: ?u8 = null,
smallest_unit: ?Unit = null, smallest_unit: ?Unit = null,
rounding_mode: ?RoundingMode = null, rounding_mode: ?RoundingMode = null,
};
pub fn toCApi(self: ToStringRoundingOptions) c.ToStringRoundingOptions { /// Time zone identifier for Temporal operations
const precision: c.Precision = if (self.fractional_second_digits) |fsd| pub const TimeZone = struct {
.{ .is_minute = false, .precision = abi.toOption(c.OptionU8, fsd) } _inner: abi.c.TimeZone,
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 .{ pub fn init(id: []const u8) TimeZone {
.precision = precision, const view = abi.toDiplomatStringView(id);
.smallest_unit = abi.toUnitOption(toCUnit(self.smallest_unit)), return .{ ._inner = .{ .id = view } };
.rounding_mode = abi.toRoundingModeOption(toCRoundingMode(self.rounding_mode)),
};
} }
}; };
pub fn toCUnit(opt: ?Unit) ?c.Unit { const abi = @import("abi.zig");
return if (opt) |u| @as(c.Unit, @intCast(u.toCApi())) else null;
}
pub fn toCRoundingMode(opt: ?RoundingMode) ?c.RoundingMode {
return if (opt) |m| @as(c.RoundingMode, @intCast(m.toCApi())) else null;
}