hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit a3a879bcc37bca30406782da8bf32ab11182068c
parent 4cc6365d9adcc291e7352e652e035371cd9b9cec
Author: Byron Torres <b@torresjrjr.com>
Date:   Thu, 22 Feb 2024 23:44:03 +0000

time::date: make type insufficient an enum

Signed-off-by: Byron Torres <b@torresjrjr.com>

Diffstat:
Mtime/date/error.ha | 14++++++++++++--
Mtime/date/virtual.ha | 26++++++++++++++++++++------
2 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/time/date/error.ha b/time/date/error.ha @@ -2,6 +2,7 @@ // (c) Hare authors <https://harelang.org> use fmt; +use strings; // All possible errors returned from [[date]]. export type error = !(insufficient | invalid | parsefail); @@ -10,8 +11,17 @@ export type error = !(insufficient | invalid | parsefail); // statically allocated. export fn strerror(err: error) const str = { match (err) { - case insufficient => - return "Insufficient date information"; + case let lack: insufficient => + static let buf: [92]u8 = [0...]; + return strings::rtrim(fmt::bsprint(buf, + "Insufficient date information, could not calculate:", + if (lack & insufficient::DAYDATE: u8 == 0) "" else + "daydate", + if (lack & insufficient::DAYTIME: u8 == 0) "" else + "time-of-day", + if (lack & insufficient::ZOFF: u8 == 0) "" else + "zone-offset", + )); case invalid => return "Invalid date information"; case let rn: parsefail => diff --git a/time/date/virtual.ha b/time/date/virtual.ha @@ -5,7 +5,13 @@ use time; use time::chrono; // A [[virtual]] does not have enough information to create a valid [[date]]. -export type insufficient = !void; +export type insufficient = !lack; // TODO: drop alias workaround + +export type lack = enum u8 { + DAYDATE = 1 << 0, // could not infer daydate + DAYTIME = 1 << 1, // could not infer time-of-day + ZOFF = 1 << 2, // could not infer zone offset +}; // A virtual date; a [[date]] wrapper interface, which represents a date of // uncertain validity. Its fields need not be valid observed chronological @@ -118,6 +124,8 @@ export fn realize( v: virtual, locs: chrono::locality... ) (date | insufficient | invalid) = { + let lacking = 0u8; + // determine .daydate if (v.daydate is i64) { void; @@ -154,13 +162,13 @@ export fn realize( void; } else { // cannot deduce daydate - return insufficient; + lacking |= insufficient::DAYDATE; }; // determine .daytime if (v.daytime is i64) { void; - } else { + } else :nodaytime { const hour = if (v.hour is int) { yield v.hour as int; } else if (v.halfhour is int && v.ampm is bool) { @@ -168,7 +176,8 @@ export fn realize( const pm = v.ampm as bool; yield if (pm) hr * 2 else hr; } else { - return insufficient; + lacking |= insufficient::DAYTIME; + yield :nodaytime; }; if ( @@ -182,8 +191,9 @@ export fn realize( v.second as int, v.nanosecond as int, )?; + lacking |= 0u8; } else { - return insufficient; + lacking |= insufficient::DAYTIME; }; }; @@ -191,7 +201,7 @@ export fn realize( if (v.zoff is i64) { void; } else { - return insufficient; + lacking |= insufficient::ZOFF; }; // determine .loc (defaults to time::chrono::UTC) @@ -208,6 +218,10 @@ export fn realize( }; }; + if (lacking != 0u8) { + return lacking: insufficient; + }; + // determine .sec, .nsec const d = from_moment(chrono::from_datetime( v.loc,