commit da7d90f25d12fa4447770d9541d9072866469a34
parent 81a06f9bb51481b711cab50d462aa9541200a6ab
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 13 Apr 2022 14:01:32 +0200
datetime: rename mock => builder
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
2 files changed, 48 insertions(+), 50 deletions(-)
diff --git a/datetime/datetime.ha b/datetime/datetime.ha
@@ -103,7 +103,7 @@ export fn new(
// TODO: improve variety of errors.
// `invaliddatetime = !void` ?
-// `invaliddatetime = !datetime::mock` ?
+// `invaliddatetime = !datetime::builder` ?
) (datetime | invalid) = {
let defaults: [_]int = [
0, 1, 1, // year month day
@@ -205,10 +205,9 @@ export fn to_instant(dt: datetime) time::instant = {
// Creates a [[datetime]] from a string, parsed according to a layout,
// using [[strategy::ALL]], or fails otherwise.
-//
-// TODO: allow the user to specify [[strategy]] for security?
export fn from_str(layout: str, s: str) (datetime | insufficient | invalid) = {
- const b = newmock();
+ // XXX: Should we allow the user to specify [[strategy]] for security?
+ const b = newbuilder();
parse(&b, layout, s)?;
return finish(&b)?;
};
@@ -223,28 +222,27 @@ export fn to_moment(dt: datetime) chrono::moment = {
};
};
-// A [[mock]] has insufficient information and cannot create a valid datetime.
+// A [[builder]] has insufficient information and cannot create a valid datetime.
export type insufficient = !void;
-// Constructs a new datetime. Start with [[newmock]]. Collect enough datetime
-// information incrementally by direct field assignments or multiple calls to
-// [[parse]]. Finish with [[finish]].
-//
-// let mock = datetime::newmock();
-// datetime::parse(&mock, "Year: %Y", "Year: 2038");
-// datetime::parse(&mock, "Month: %m", "Month: 01");
-// mock.day = 19;
-// let dt = datetime::finish(&mock, datetime::strategy::YMD);
+// Constructs a new datetime. Start with [[newbuilder]], then collect enough
+// datetime information incrementally by direct field assignments and/or one or
+// more calls to [[parse]]. Finish with [[finish]].
//
-export type mock = datetime;
-
-// Creates a new [[mock]]
-export fn newmock() mock = init(): mock;
-
-// Returns a datetime from a mock. The provided [[strategy]]s will be tried in
-// order until a valid datetime is produced, or fail otherwise. The default
+// let builder = datetime::newbuilder();
+// datetime::parse(&builder, "Year: %Y", "Year: 2038");
+// datetime::parse(&builder, "Month: %m", "Month: 01");
+// builder.day = 19;
+// let dt = datetime::finish(&builder, datetime::strategy::YMD);
+export type builder = datetime;
+
+// Creates a new [[builder]]
+export fn newbuilder() builder = init(): builder;
+
+// Returns a datetime from a builder. The provided [[strategy]]s will be tried
+// in order until a valid datetime is produced, or fail otherwise. The default
// strategy is [[strategy::ALL]].
-export fn finish(f: *mock, m: strategy...) (datetime | insufficient | invalid) = {
+export fn finish(f: *builder, m: strategy...) (datetime | insufficient | invalid) = {
if (len(m) == 0) {
m = [strategy::ALL];
};
@@ -297,7 +295,7 @@ export fn finish(f: *mock, m: strategy...) (datetime | insufficient | invalid) =
return insufficient;
};
-// Specifies which [[mock]] fields (and what strategy) to use to calculate the
+// Specifies which [[builder]] fields (and what strategy) to use to calculate the
// epochal, and thus a valid datetime.
export type strategy = enum uint {
// year, month, day
diff --git a/datetime/parse.ha b/datetime/parse.ha
@@ -1,14 +1,14 @@
use errors;
use strings;
-// Parses a datetime string into a [[mock]], using a "layout" format string
+// Parses a datetime string into a [[builder]], using a "layout" format string
// with a subset of specifiers from POSIX strptime(3). Partial, incremental
// parsing is possible.
//
-// datetime::parse(&mok, "%Y-%m-%d", "2038-01-19");
-// datetime::parse(&mok, "%H:%M:%S", "03:14:07");
+// datetime::parse(&builder, "%Y-%m-%d", "2038-01-19");
+// datetime::parse(&builder, "%H:%M:%S", "03:14:07");
//
-export fn parse(mok: *mock, layout: str, s: str) (void | invalid) = {
+export fn parse(build: *builder, layout: str, s: str) (void | invalid) = {
const format_iter = strings::iter(layout);
const s_iter = strings::iter(s);
let escaped = false;
@@ -42,29 +42,29 @@ export fn parse(mok: *mock, layout: str, s: str) (void | invalid) = {
switch (format_r) {
// Basic specifiers
case 'a' =>
- mok.weekday = get_default_locale_string_index(
+ build.weekday = get_default_locale_string_index(
&s_iter, WEEKDAYS_SHORT[..])?;
case 'A' =>
- mok.weekday = get_default_locale_string_index(
+ build.weekday = get_default_locale_string_index(
&s_iter, WEEKDAYS[..])?;
case 'b' =>
- mok.month = get_default_locale_string_index(
+ build.month = get_default_locale_string_index(
&s_iter, MONTHS_SHORT[..])?;
case 'B' =>
- mok.month = get_default_locale_string_index(
+ build.month = get_default_locale_string_index(
&s_iter, MONTHS[..])?;
case 'd' =>
let max_n_digits = 2u;
- mok.day = clamp_int(
+ build.day = clamp_int(
get_max_n_digits(&s_iter, max_n_digits)?, 1, 31);
case 'H' =>
let max_n_digits = 2u;
- mok.hour = clamp_int(
+ build.hour = clamp_int(
get_max_n_digits(&s_iter, max_n_digits)?, 0, 23);
case 'I' =>
let max_n_digits = 2u;
const hour = get_max_n_digits(&s_iter, max_n_digits);
- mok.hour = match (hour) {
+ build.hour = match (hour) {
case let hour: int =>
yield if (hour > 12) {
yield clamp_int(hour - 12, 1, 12);
@@ -75,38 +75,38 @@ export fn parse(mok: *mock, layout: str, s: str) (void | invalid) = {
return invalid;
};
case 'j' =>
- mok.yearday = clamp_int(
+ build.yearday = clamp_int(
get_max_n_digits(&s_iter, 3)?, 1, 366);
case 'm' =>
- mok.month = clamp_int(
+ build.month = clamp_int(
get_max_n_digits(&s_iter, 2)?, 1, 12);
case 'M' =>
- mok.min = clamp_int(
+ build.min = clamp_int(
get_max_n_digits(&s_iter, 2)?, 0, 59);
case 'N' =>
- mok.nsec = clamp_int(
+ build.nsec = clamp_int(
get_max_n_digits(&s_iter, 3)?, 0, 999);
case 'p' =>
- if (mok.hour is void) {
+ if (build.hour is void) {
// We can't change the hour's am/pm because we
// have no hour.
return invalid;
};
const rest = strings::iterstr(&s_iter);
if (strings::hasprefix(rest, "AM")) {
- if (mok.hour as int > 12) {
+ if (build.hour as int > 12) {
// 13 AM?
return invalid;
- } else if (mok.hour as int == 12) {
- mok.hour = 0;
+ } else if (build.hour as int == 12) {
+ build.hour = 0;
};
} else if (strings::hasprefix(rest, "PM")) {
- if (mok.hour as int > 12) {
+ if (build.hour as int > 12) {
// 13 PM?
return invalid;
- } else if (mok.hour as int < 12) {
- mok.hour =
- (mok.hour as int) + 12;
+ } else if (build.hour as int < 12) {
+ build.hour =
+ (build.hour as int) + 12;
};
} else {
return invalid;
@@ -114,10 +114,10 @@ export fn parse(mok: *mock, layout: str, s: str) (void | invalid) = {
strings::next(&s_iter);
strings::next(&s_iter);
case 'S' =>
- mok.sec = clamp_int(
+ build.sec = clamp_int(
get_max_n_digits(&s_iter, 2)?, 0, 61);
case 'u', 'w' =>
- mok.weekday = match (get_max_n_digits(&s_iter, 1)) {
+ build.weekday = match (get_max_n_digits(&s_iter, 1)) {
case let i: int =>
yield if (format_r == 'w') {
yield if (i == 0) {
@@ -132,10 +132,10 @@ export fn parse(mok: *mock, layout: str, s: str) (void | invalid) = {
return invalid;
};
case 'U', 'W' =>
- mok.week = clamp_int(
+ build.week = clamp_int(
get_max_n_digits(&s_iter, 2)?, 0, 53);
case 'Y' =>
- mok.year = get_max_n_digits(&s_iter, 4)?;
+ build.year = get_max_n_digits(&s_iter, 4)?;
case 'z' =>
// TODO
continue;