feat(pdt): make overloading ctor

This commit is contained in:
Nurul Huda (Apon) 2026-01-28 10:39:52 +06:00
parent f0419f34ab
commit 68f2bad1a8
No known key found for this signature in database
GPG key ID: 5D3F1DE2855A2F79

View file

@ -48,7 +48,40 @@ pub const WithOptions = struct {
microsecond: ?u16 = null, microsecond: ?u16 = null,
nanosecond: ?u16 = null, nanosecond: ?u16 = null,
}; };
const PartialDateTime = struct {};
const FromOptions = struct {
overflow: ?Overflow = null,
};
const Overflow = enum {
constrain,
reject,
fn toCApi(self: Overflow) abi.c.ArithmeticOverflow {
return switch (self) {
.constrain => abi.c.ArithmeticOverflow_Constrain,
.reject => abi.c.ArithmeticOverflow_Reject,
};
}
};
const PartialDateTime = struct {
// Date fields (recognized by PlainDate.from)
calendar: ?[]const u8 = null,
era: ?[]const u8 = null,
eraYear: ?u32 = null,
year: ?i32 = null,
month: ?u8 = null,
monthCode: ?[]const u8 = null,
day: ?u8 = null,
// Time fields (recognized by PlainTime.from)
hour: ?u8 = null,
minute: ?u8 = null,
second: ?u8 = null,
millisecond: ?u16 = null,
microsecond: ?u16 = null,
nanosecond: ?u16 = null,
};
// Constructor - creates a PlainDateTime with all parameters // Constructor - creates a PlainDateTime with all parameters
pub fn init( pub fn init(
@ -105,40 +138,34 @@ pub fn calInit(
)); ));
} }
// Parse from string const FromInit = union(enum) { plain_date: PlainDate, plain_date_time: PlainDateTime };
pub fn from(info: anytype) !PlainDateTime {
// Parse from string or object
pub fn from(info: anytype, opts: FromOptions) !PlainDateTime {
const T = @TypeOf(info); const T = @TypeOf(info);
const overflow = if (opts.overflow) |f| f.toCApi() else null;
if (T == PlainDateTime) return info.clone(); if (T == PlainDateTime) return info.clone();
if (T == PartialDateTime) return fromPartial(info); if (T == PlainTime) return abi.c.temporal_rs_PlainDateTime_from_partial(.{ .time = info._inner }, abi.toArithmeticOverflowOption(overflow));
if (T == PlainDate) return abi.c.temporal_rs_PlainDateTime_from_partial(.{ .date = info._inner }, abi.toArithmeticOverflowOption(overflow));
// Handle string types (both literals and slices) // Handle string types (both literals and slices)
const type_info = @typeInfo(T); const type_info = @typeInfo(T);
switch (type_info) { switch (type_info) {
.pointer => { .pointer => |ptr_info| {
const ptr = type_info.pointer; const ChildType = switch (@typeInfo(ptr_info.child)) {
const ChildType = switch (@typeInfo(ptr.child)) {
.array => |arr| arr.child, .array => |arr| arr.child,
else => ptr.child, else => ptr_info.child,
}; };
if (ChildType == u8) return fromUtf8(info); if (ChildType == u8) return fromUtf8(info);
if (ChildType == u16) return fromUtf16(info); if (ChildType == u16) return fromUtf16(info);
return abi.TemporalError.Generic;
}, },
else => @compileError("from() expects a Duration, []const u8, or []const u16, or Temporal.Duration.PartialDuration"), else => return abi.TemporalError.Generic,
} }
} }
fn fromPartial(info: PartialDateTime) !PlainDateTime {
_ = info;
return error.NotImplemented;
// return abi.c.temporal_rs_PlainDateTime_from_partial(.{
// .date = .{
// .
// }
// }, overflow: struct_ArithmeticOverflow_option)
}
fn fromUtf8(utf8: []const u8) !PlainDateTime { fn fromUtf8(utf8: []const u8) !PlainDateTime {
const view = abi.toDiplomatStringView(utf8); const view = abi.toDiplomatStringView(utf8);
const parsed = abi.c.temporal_rs_ParsedDateTime_from_utf8(view); const parsed = abi.c.temporal_rs_ParsedDateTime_from_utf8(view);
@ -168,6 +195,7 @@ pub fn add(self: PlainDateTime, duration: Duration) !PlainDateTime {
.is_ok = true, .is_ok = true,
.unnamed_0 = .{ .ok = abi.c.ArithmeticOverflow_Constrain }, .unnamed_0 = .{ .ok = abi.c.ArithmeticOverflow_Constrain },
}; };
return wrapPlainDateTime(abi.c.temporal_rs_PlainDateTime_add(self._inner, duration._inner, overflow_opt)); return wrapPlainDateTime(abi.c.temporal_rs_PlainDateTime_add(self._inner, duration._inner, overflow_opt));
} }
@ -441,12 +469,11 @@ pub fn valueOf(self: PlainDateTime) !void {
// Helper functions // Helper functions
fn clone(self: PlainDateTime) PlainDateTime { fn clone(self: PlainDateTime) PlainDateTime {
return self; return abi.c.temporal_rs_PlainDateTime_clone(self._inner);
} }
pub fn deinit(self: *PlainDateTime) void { pub fn deinit(self: *PlainDateTime) void {
_ = self; abi.c.temporal_rs_PlainDateTime_destroy(self._inner);
// The C API manages memory
} }
fn wrapPlainDateTime(res: anytype) !PlainDateTime { fn wrapPlainDateTime(res: anytype) !PlainDateTime {
@ -467,7 +494,7 @@ test init {
} }
test from { test from {
const dt = try PlainDateTime.from("2024-01-15T14:30:45"); const dt = try PlainDateTime.from("2024-01-15T14:30:45", .{});
try std.testing.expectEqual(@as(i32, 2024), dt.year()); try std.testing.expectEqual(@as(i32, 2024), dt.year());
try std.testing.expectEqual(@as(u8, 1), dt.month()); try std.testing.expectEqual(@as(u8, 1), dt.month());
try std.testing.expectEqual(@as(u8, 15), dt.day()); try std.testing.expectEqual(@as(u8, 15), dt.day());