refactor: remove internal allocator usage

This commit is contained in:
Nurul Huda (Apon) 2026-01-26 23:14:43 +06:00
parent f88236cf31
commit 7f5b8e4e5b
5 changed files with 106 additions and 119 deletions

View file

@ -42,7 +42,6 @@ pub const ToZonedDateTimeOptions = struct {
}; };
_inner: *abi.c.PlainDate, _inner: *abi.c.PlainDate,
calendar_id: []const u8,
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 initWithCalendar(year_val, month_val, day_val, "iso8601"); return initWithCalendar(year_val, month_val, day_val, "iso8601");
@ -126,28 +125,23 @@ pub fn withCalendar(self: PlainDate, calendar: []const u8) !PlainDate {
const cal_kind = abi.success(cal_result) orelse return error.TemporalError; const cal_kind = abi.success(cal_result) orelse return error.TemporalError;
const ptr = abi.c.temporal_rs_PlainDate_with_calendar(self._inner, cal_kind) orelse return error.TemporalError; const ptr = abi.c.temporal_rs_PlainDate_with_calendar(self._inner, cal_kind) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
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) |t| t._inner else null;
const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_date_time(self._inner, time_ptr)) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_date_time(self._inner, time_ptr)) orelse return error.TemporalError) orelse return error.TemporalError;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
pub fn toPlainMonthDay(self: PlainDate) !PlainMonthDay { pub fn toPlainMonthDay(self: PlainDate) !PlainMonthDay {
const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_month_day(self._inner)) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_month_day(self._inner)) orelse return error.TemporalError) orelse return error.TemporalError;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
pub fn toPlainYearMonth(self: PlainDate) !PlainYearMonth { pub fn toPlainYearMonth(self: PlainDate) !PlainYearMonth {
const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_year_month(self._inner)) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_plain_year_month(self._inner)) orelse return error.TemporalError) orelse return error.TemporalError;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
pub fn toZonedDateTime(self: PlainDate, options: ToZonedDateTimeOptions) !ZonedDateTime { pub fn toZonedDateTime(self: PlainDate, options: ToZonedDateTimeOptions) !ZonedDateTime {
@ -159,13 +153,13 @@ pub fn toZonedDateTime(self: PlainDate, options: ToZonedDateTimeOptions) !ZonedD
const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_zoned_date_time(self._inner, time_zone, time_ptr)) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_zoned_date_time(self._inner, time_zone, time_ptr)) orelse return error.TemporalError) orelse return error.TemporalError;
// Get time zone identifier for ZonedDateTime // Get time zone identifier for ZonedDateTime
const allocator = std.heap.page_allocator; // const allocator = std.heap.page_allocator;
var write = abi.DiplomatWrite.init(allocator); // var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); // defer write.deinit();
abi.c.temporal_rs_TimeZone_identifier(time_zone, &write.inner); // abi.c.temporal_rs_TimeZone_identifier(time_zone, &write.inner);
const tz_id = try write.toOwnedSlice(); // const tz_id = try write.toOwnedSlice();
return .{ ._inner = ptr, .time_zone_id = tz_id, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
pub fn toString(self: PlainDate, allocator: std.mem.Allocator, options: ToStringOptions) ![]u8 { pub fn toString(self: PlainDate, allocator: std.mem.Allocator, options: ToStringOptions) ![]u8 {
@ -246,6 +240,12 @@ pub fn inLeapYear(self: PlainDate) bool {
return abi.c.temporal_rs_PlainDate_in_leap_year(self._inner); return abi.c.temporal_rs_PlainDate_in_leap_year(self._inner);
} }
pub fn calendarId(self: PlainDate, allocator: std.mem.Allocator) ![]u8 {
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(self._inner) orelse return error.TemporalError;
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
return try allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]);
}
pub fn era(self: PlainDate, allocator: std.mem.Allocator) !?[]u8 { pub fn era(self: PlainDate, allocator: std.mem.Allocator) !?[]u8 {
var write = abi.DiplomatWrite.init(allocator); var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); defer write.deinit();
@ -275,7 +275,7 @@ pub fn yearOfWeek(self: PlainDate) ?i32 {
fn clone(self: PlainDate) PlainDate { fn clone(self: PlainDate) PlainDate {
const ptr = abi.c.temporal_rs_PlainDate_clone(self._inner) orelse unreachable; const ptr = abi.c.temporal_rs_PlainDate_clone(self._inner) orelse unreachable;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
pub fn deinit(self: PlainDate) void { pub fn deinit(self: PlainDate) void {
@ -285,13 +285,13 @@ pub fn deinit(self: PlainDate) void {
fn wrapPlainDate(res: anytype) !PlainDate { fn wrapPlainDate(res: anytype) !PlainDate {
const ptr = (abi.success(res) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(res) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) orelse return error.TemporalError; // const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) 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);
const allocator = std.heap.page_allocator; // const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601"; // const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id }; return .{ ._inner = ptr };
} }
fn handleVoidResult(res: anytype) !void { fn handleVoidResult(res: anytype) !void {
@ -471,12 +471,11 @@ test toPlainYearMonth {
} }
test toZonedDateTime { test toZonedDateTime {
if (true) return error.SkipZigTest; // ZonedDateTime not fully implemented yet const date = try PlainDate.init(2024, 1, 15);
// const date = try PlainDate.init(2024, 1, 15); const zdt = try date.toZonedDateTime(.{ .time_zone = "UTC", .plain_time = null });
// const zdt = try date.toZonedDateTime(.{ .time_zone = "UTC", .plain_time = null }); try std.testing.expectEqual(@as(i32, 2024), zdt.year());
// try std.testing.expectEqual(@as(i32, 2024), zdt.year()); try std.testing.expectEqual(@as(u8, 1), zdt.month());
// try std.testing.expectEqual(@as(u8, 1), zdt.month()); try std.testing.expectEqual(@as(u8, 15), zdt.day());
// try std.testing.expectEqual(@as(u8, 15), zdt.day());
} }
test with { test with {

View file

@ -10,7 +10,6 @@ const Duration = @import("Duration.zig");
const PlainDateTime = @This(); const PlainDateTime = @This();
_inner: *abi.c.PlainDateTime, _inner: *abi.c.PlainDateTime,
calendar_id: []const u8,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal.Unit; pub const Unit = temporal.Unit;
@ -130,8 +129,7 @@ pub fn compare(a: PlainDateTime, b: PlainDateTime) i8 {
} }
pub fn equals(self: PlainDateTime, other: PlainDateTime) bool { pub fn equals(self: PlainDateTime, other: PlainDateTime) bool {
if (compare(self, other) != 0) return false; return compare(self, other) == 0;
return std.mem.eql(u8, self.calendar_id, other.calendar_id);
} }
// Arithmetic // Arithmetic
@ -169,8 +167,10 @@ pub fn round(self: PlainDateTime, options: RoundOptions) !PlainDateTime {
} }
// Property accessors - Date fields // Property accessors - Date fields
pub fn calendarId(self: PlainDateTime) []const u8 { pub fn calendarId(self: PlainDateTime, allocator: std.mem.Allocator) ![]u8 {
return self.calendar_id; 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);
return try allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]);
} }
pub fn day(self: PlainDateTime) u8 { pub fn day(self: PlainDateTime) u8 {
@ -287,7 +287,9 @@ pub fn with(self: PlainDateTime, partial: WithOptions) !PlainDateTime {
const new_nanosecond = partial.nanosecond orelse self.nanosecond(); const new_nanosecond = partial.nanosecond orelse self.nanosecond();
// Preserve calendar // Preserve calendar
const cal_view = abi.toDiplomatStringView(self.calendar_id); 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_view = abi.c.DiplomatStringView{ .data = cal_id_view.data, .len = cal_id_view.len };
const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view); const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view);
const cal_kind = abi.success(cal_result) orelse return error.TemporalError; const cal_kind = abi.success(cal_result) orelse return error.TemporalError;
@ -311,12 +313,7 @@ pub fn withCalendar(self: PlainDateTime, calendar: []const u8) !PlainDateTime {
const cal_kind = abi.success(cal_result) orelse return error.TemporalError; const cal_kind = abi.success(cal_result) orelse return error.TemporalError;
const ptr = abi.c.temporal_rs_PlainDateTime_with_calendar(self._inner, cal_kind) orelse return error.TemporalError; const ptr = abi.c.temporal_rs_PlainDateTime_with_calendar(self._inner, cal_kind) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDateTime_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime { pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime {
@ -327,7 +324,9 @@ pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime {
const new_microsecond: u16 = if (time) |t| t.microsecond() else 0; const new_microsecond: u16 = if (time) |t| t.microsecond() else 0;
const new_nanosecond: u16 = if (time) |t| t.nanosecond() else 0; const new_nanosecond: u16 = if (time) |t| t.nanosecond() else 0;
const cal_view = abi.toDiplomatStringView(self.calendar_id); 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_view = abi.c.DiplomatStringView{ .data = cal_id_view.data, .len = cal_id_view.len };
const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view); const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view);
const cal_kind = abi.success(cal_result) orelse return error.TemporalError; const cal_kind = abi.success(cal_result) orelse return error.TemporalError;
@ -349,12 +348,7 @@ pub fn withPlainTime(self: PlainDateTime, time: ?PlainTime) !PlainDateTime {
pub fn toPlainDate(self: PlainDateTime) !PlainDate { pub fn toPlainDate(self: PlainDateTime) !PlainDate {
const ptr = abi.c.temporal_rs_PlainDateTime_to_plain_date(self._inner) orelse return error.TemporalError; const ptr = abi.c.temporal_rs_PlainDateTime_to_plain_date(self._inner) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
pub fn toPlainTime(self: PlainDateTime) !PlainTime { pub fn toPlainTime(self: PlainDateTime) !PlainTime {
@ -374,12 +368,7 @@ pub fn toZonedDateTime(self: PlainDateTime, options: ToZonedDateTimeOptions) !Zo
// Use PlainDate's toZonedDateTime with the time component // Use PlainDate's toZonedDateTime with the time component
const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_zoned_date_time(date._inner, time_zone, time._inner)) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(abi.c.temporal_rs_PlainDate_to_zoned_date_time(date._inner, time_zone, time._inner)) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_ZonedDateTime_calendar(ptr); return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
pub fn toString(self: PlainDateTime, allocator: std.mem.Allocator, options: ToStringOptions) ![]u8 { pub fn toString(self: PlainDateTime, allocator: std.mem.Allocator, options: ToStringOptions) ![]u8 {
@ -433,13 +422,7 @@ pub fn deinit(self: *PlainDateTime) void {
fn wrapPlainDateTime(res: anytype) !PlainDateTime { fn wrapPlainDateTime(res: anytype) !PlainDateTime {
const ptr = (abi.success(res) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(res) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDateTime_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
// ---------- Tests --------------------- // ---------- Tests ---------------------
@ -588,7 +571,9 @@ test withCalendar {
const result = try dt.withCalendar("iso8601"); const result = try dt.withCalendar("iso8601");
try std.testing.expectEqual(@as(i32, 2024), result.year()); try std.testing.expectEqual(@as(i32, 2024), result.year());
try std.testing.expectEqualStrings("iso8601", result.calendar_id); const cal_id = try result.calendarId(std.testing.allocator);
defer std.testing.allocator.free(cal_id);
try std.testing.expectEqualStrings("iso8601", cal_id);
} }
test withPlainTime { test withPlainTime {

View file

@ -6,7 +6,6 @@ const PlainMonthDay = @This();
const PlainDate = @import("PlainDate.zig"); const PlainDate = @import("PlainDate.zig");
_inner: *abi.c.PlainMonthDay, _inner: *abi.c.PlainMonthDay,
calendar_id: []const u8,
// Type definitions for API compatibility // Type definitions for API compatibility
pub const CalendarDisplay = enum { pub const CalendarDisplay = enum {
@ -29,13 +28,7 @@ pub const WithOptions = struct {
fn wrapPlainMonthDay(result: anytype) !PlainMonthDay { fn wrapPlainMonthDay(result: anytype) !PlainMonthDay {
const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainMonthDay_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
// Constructor // Constructor
@ -79,8 +72,10 @@ pub fn equals(self: PlainMonthDay, other: PlainMonthDay) bool {
} }
// Property accessors // Property accessors
pub fn calendarId(self: PlainMonthDay) []const u8 { pub fn calendarId(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
return self.calendar_id; const calendar_ptr = abi.c.temporal_rs_PlainMonthDay_calendar(self._inner) orelse return error.TemporalError;
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
return try allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]);
} }
pub fn day(self: PlainMonthDay) u8 { pub fn day(self: PlainMonthDay) u8 {
@ -146,13 +141,7 @@ pub fn toPlainDate(self: PlainMonthDay, year: i32) !PlainDate {
const result = abi.c.temporal_rs_PlainMonthDay_to_plain_date(self._inner, partial_date); const result = abi.c.temporal_rs_PlainMonthDay_to_plain_date(self._inner, partial_date);
const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) orelse return error.TemporalError; return PlainDate{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return PlainDate{ ._inner = ptr, .calendar_id = cal_id };
} }
// String conversions // String conversions

View file

@ -7,7 +7,6 @@ const PlainDate = @import("PlainDate.zig");
const Duration = @import("Duration.zig"); const Duration = @import("Duration.zig");
_inner: *abi.c.PlainYearMonth, _inner: *abi.c.PlainYearMonth,
calendar_id: []const u8,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal_types.Unit; pub const Unit = temporal_types.Unit;
@ -37,13 +36,7 @@ pub const WithOptions = struct {
fn wrapPlainYearMonth(result: anytype) !PlainYearMonth { fn wrapPlainYearMonth(result: anytype) !PlainYearMonth {
const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainYearMonth_calendar(ptr) orelse return error.TemporalError; return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
// Constructor // Constructor
@ -116,8 +109,10 @@ pub fn since(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSet
} }
// Property accessors // Property accessors
pub fn calendarId(self: PlainYearMonth) []const u8 { pub fn calendarId(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
return self.calendar_id; const calendar_ptr = abi.c.temporal_rs_PlainYearMonth_calendar(self._inner) orelse return error.TemporalError;
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
return try allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]);
} }
pub fn year(self: PlainYearMonth) i32 { pub fn year(self: PlainYearMonth) i32 {
@ -128,8 +123,7 @@ pub fn month(self: PlainYearMonth) u8 {
return abi.c.temporal_rs_PlainYearMonth_month(self._inner); return abi.c.temporal_rs_PlainYearMonth_month(self._inner);
} }
pub fn monthCode(self: PlainYearMonth) ![]const u8 { pub fn monthCode(self: PlainYearMonth, allocator: std.mem.Allocator) ![]const u8 {
const allocator = std.heap.page_allocator;
var write = abi.DiplomatWrite.init(allocator); var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); defer write.deinit();
@ -153,8 +147,7 @@ pub fn inLeapYear(self: PlainYearMonth) bool {
return abi.c.temporal_rs_PlainYearMonth_in_leap_year(self._inner); return abi.c.temporal_rs_PlainYearMonth_in_leap_year(self._inner);
} }
pub fn era(self: PlainYearMonth) !?[]const u8 { pub fn era(self: PlainYearMonth, allocator: std.mem.Allocator) !?[]const u8 {
const allocator = std.heap.page_allocator;
var write = abi.DiplomatWrite.init(allocator); var write = abi.DiplomatWrite.init(allocator);
defer write.deinit(); defer write.deinit();
@ -221,13 +214,7 @@ pub fn toPlainDate(self: PlainYearMonth, day: u8) !PlainDate {
const result = abi.c.temporal_rs_PlainYearMonth_to_plain_date(self._inner, partial_date); const result = abi.c.temporal_rs_PlainYearMonth_to_plain_date(self._inner, partial_date);
const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_PlainDate_calendar(ptr) orelse return error.TemporalError; return PlainDate{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.page_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return PlainDate{ ._inner = ptr, .calendar_id = cal_id };
} }
// String conversions // String conversions
@ -416,3 +403,39 @@ test toLocaleString {
try std.testing.expect(str.len > 0); try std.testing.expect(str.len > 0);
try std.testing.expect(std.mem.indexOf(u8, str, "2024") != null); try std.testing.expect(std.mem.indexOf(u8, str, "2024") != null);
} }
test "props" {
const ym = try from("2021-07-01[u-ca=gregory]");
const cal_id = try ym.calendarId(std.testing.allocator);
defer std.testing.allocator.free(cal_id);
try std.testing.expectEqualStrings("gregory", cal_id);
try std.testing.expectEqual(@as(i32, 2021), ym.year());
try std.testing.expectEqual(@as(u8, 7), ym.month());
const month_code = try ym.monthCode(std.testing.allocator);
defer std.testing.allocator.free(month_code);
try std.testing.expectEqualStrings("M07", month_code);
try std.testing.expectEqual(@as(u16, 31), ym.daysInMonth());
try std.testing.expectEqual(@as(u16, 365), ym.daysInYear());
try std.testing.expectEqual(@as(u16, 12), ym.monthsInYear());
try std.testing.expect(ym.inLeapYear() == false);
const eraa = try ym.era(std.testing.allocator);
if (eraa) |e| {
defer std.testing.allocator.free(e);
std.debug.print("Era: {s}\n", .{e});
try std.testing.expectEqualStrings("ce", e);
} else {
try std.testing.expect(false);
}
const era_year = ym.eraYear();
if (era_year) |ey| {
std.debug.print("Era Year: {d}\n", .{ey});
try std.testing.expectEqual(@as(i32, 2021), ey);
} else {
try std.testing.expect(false);
}
}

View file

@ -11,7 +11,6 @@ const Duration = @import("Duration.zig");
const ZonedDateTime = @This(); const ZonedDateTime = @This();
_inner: *abi.c.ZonedDateTime, _inner: *abi.c.ZonedDateTime,
calendar_id: []const u8,
// Import types from temporal.zig // Import types from temporal.zig
pub const Unit = temporal_types.Unit; pub const Unit = temporal_types.Unit;
@ -121,11 +120,7 @@ pub const ToStringOptions = struct {
/// Helper function to wrap a C API result into a ZonedDateTime /// Helper function to wrap a C API result into a ZonedDateTime
fn wrapZonedDateTime(result: anytype) !ZonedDateTime { fn wrapZonedDateTime(result: anytype) !ZonedDateTime {
const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError; const ptr = (abi.success(result) orelse return error.TemporalError) orelse return error.TemporalError;
const calendar_ptr = abi.c.temporal_rs_ZonedDateTime_calendar(ptr); return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.c_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
/// Create a ZonedDateTime from epoch nanoseconds /// Create a ZonedDateTime from epoch nanoseconds
@ -177,11 +172,7 @@ pub fn getTimeZoneTransition(self: ZonedDateTime, direction: enum { next, previo
const result = abi.c.temporal_rs_ZonedDateTime_get_time_zone_transition(self._inner, dir); const result = abi.c.temporal_rs_ZonedDateTime_get_time_zone_transition(self._inner, dir);
const maybe_ptr = abi.success(result) orelse return error.TemporalError; const maybe_ptr = abi.success(result) orelse return error.TemporalError;
if (maybe_ptr) |ptr| { if (maybe_ptr) |ptr| {
const calendar_ptr = abi.c.temporal_rs_ZonedDateTime_calendar(ptr); return .{ ._inner = ptr };
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
const allocator = std.heap.c_allocator;
const cal_id = allocator.dupe(u8, cal_id_view.data[0..cal_id_view.len]) catch "iso8601";
return .{ ._inner = ptr, .calendar_id = cal_id };
} }
return null; return null;
} }
@ -230,13 +221,13 @@ pub fn toLocaleString(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
/// Convert to PlainDate /// Convert to PlainDate
pub fn toPlainDate(self: ZonedDateTime) !PlainDate { pub fn toPlainDate(self: ZonedDateTime) !PlainDate {
const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_date(self._inner) orelse return error.TemporalError; const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_date(self._inner) orelse return error.TemporalError;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
/// Convert to PlainDateTime /// Convert to PlainDateTime
pub fn toPlainDateTime(self: ZonedDateTime) !PlainDateTime { pub fn toPlainDateTime(self: ZonedDateTime) !PlainDateTime {
const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_datetime(self._inner) orelse return error.TemporalError; const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_datetime(self._inner) orelse return error.TemporalError;
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
/// Convert to PlainTime /// Convert to PlainTime
@ -432,7 +423,7 @@ pub fn second(self: ZonedDateTime) u8 {
pub fn timeZoneId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 { pub fn timeZoneId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
const tz = abi.c.temporal_rs_ZonedDateTime_timezone(self._inner); const tz = abi.c.temporal_rs_ZonedDateTime_timezone(self._inner);
const view = abi.fromDiplomatStringView(tz.id); const view = abi.fromDiplomatStringView(tz.normalized_id);
return try allocator.dupe(u8, view); return try allocator.dupe(u8, view);
} }
@ -453,15 +444,12 @@ pub fn yearOfWeek(self: ZonedDateTime) ?i32 {
/// Clone this ZonedDateTime /// Clone this ZonedDateTime
pub fn clone(self: ZonedDateTime) ZonedDateTime { pub fn clone(self: ZonedDateTime) ZonedDateTime {
const ptr = abi.c.temporal_rs_ZonedDateTime_clone(self._inner); const ptr = abi.c.temporal_rs_ZonedDateTime_clone(self._inner);
return .{ ._inner = ptr, .calendar_id = self.calendar_id }; return .{ ._inner = ptr };
} }
/// Free the ZonedDateTime /// Free the ZonedDateTime
pub fn deinit(self: ZonedDateTime) void { pub fn deinit(self: ZonedDateTime) void {
abi.c.temporal_rs_ZonedDateTime_destroy(self._inner); abi.c.temporal_rs_ZonedDateTime_destroy(self._inner);
if (self.calendar_id.len > 0) {
std.heap.c_allocator.free(self.calendar_id);
}
} }
// ---------- Tests --------------------- // ---------- Tests ---------------------
@ -566,8 +554,7 @@ test toPlainTime {
test toString { test toString {
if (true) return error.Todo; if (true) return error.Todo;
const tz = try TimeZone.init("UTC"); const zdt = try from("2021-01-01T00:00:00+00:00[UTC]", null, .compatible, .reject);
const zdt = try fromEpochMilliseconds(1609459200000, tz);
defer zdt.deinit(); defer zdt.deinit();
const str = try zdt.toString(std.testing.allocator, .{}); const str = try zdt.toString(std.testing.allocator, .{});
@ -588,4 +575,8 @@ test "props" {
try std.testing.expectEqual(@as(u8, 0), zdt.minute()); try std.testing.expectEqual(@as(u8, 0), zdt.minute());
try std.testing.expectEqual(@as(u8, 0), zdt.second()); try std.testing.expectEqual(@as(u8, 0), zdt.second());
try std.testing.expectEqual(@as(u16, 0), zdt.millisecond()); try std.testing.expectEqual(@as(u16, 0), zdt.millisecond());
// const tzo = try zdt.timeZoneId(std.testing.allocator);
// defer std.testing.allocator.free(tzo);
// try std.testing.expectEqualStrings("UTC", tzo);
} }