~torresjrjr/hare

46910b1f3e41daf1b3ccf57309e8eaa96f741139 — Byron Torres 6 months ago bf79c5b
time: new type order; time::compare returns order

Adds type safety to [[time::compare]] and other time comparing code.
Exhausts switch statements (no more catch-all "Unreachable" aborts).
Convenient numerical literals can still be used in place of enum values.
4 files changed, 13 insertions(+), 10 deletions(-)

M time/arithm.ha
M time/chrono/timescale.ha
M time/chrono/timezone.ha
M time/types.ha
M time/arithm.ha => time/arithm.ha +6 -6
@@ 29,12 29,12 @@ export fn diff(a: instant, b: instant) duration = {

// Returns -1 if a precedes b, 0 if a and b are simultaneous, or +1 if b
// precedes a.
export fn compare(a: instant, b: instant) i8 = {
	return if (a.sec < b.sec) -1
	else if (a.sec > b.sec) 1
	else if (a.nsec < b.nsec) -1
	else if (a.nsec > b.nsec) 1
	else 0;
export fn compare(a: instant, b: instant) order = {
	return if (a.sec < b.sec) order::BEFORE
	else if (a.sec > b.sec) order::AFTER
	else if (a.nsec < b.nsec) order::BEFORE
	else if (a.nsec > b.nsec) order::AFTER
	else order::SAME;
};

// Scales the given [[instant]]'s scalar value by a factor 'f'. Make sure to

M time/chrono/timescale.ha => time/chrono/timescale.ha +0 -2
@@ 108,8 108,6 @@ fn lookup_leaps(list: *[](i64, i64), t: i64) size = {
			lo = mid; break;
		case 1 =>
			lo = mid;
		case =>
			abort("Unreachable");
		};
	};
	return lo;

M time/chrono/timezone.ha => time/chrono/timezone.ha +0 -2
@@ 148,8 148,6 @@ export fn lookupzone(m: *moment) zone = {
			lo = mid; break;
		case 1 =>
			lo = mid;
		case =>
			abort("Unreachable");
		};
	};


M time/types.ha => time/types.ha +7 -0
@@ 36,6 36,13 @@ export type instant = struct {
// Represents a unique interval of time between two [[instant]]s.
export type interval = (instant, instant);

// A union of possible temporal orderings of [[instant]]s.
export type order = enum i8 {
	BEFORE = -1,
	SAME   =  0,
	AFTER  = +1,
};

// All error types which are concerned with the handling of [[instant]]s.
export type error = !(ambiguous | nonexistent);