aboutsummaryrefslogtreecommitdiff
path: root/distamp.ha
diff options
context:
space:
mode:
authorJulian Hurst <ark@mansus.space>2024-09-27 11:56:31 +0200
committerJulian Hurst <ark@mansus.space>2024-09-27 11:56:31 +0200
commit401d4ac152da60839972606b7104b45f69cc9e5e (patch)
treec0ea0a04fd860c1d40b780bd61a19a00ec08f5a2 /distamp.ha
parent5b48e9c9e172ff322cc7e4dde118aa49829b79d9 (diff)
downloaddistamp-401d4ac152da60839972606b7104b45f69cc9e5e.tar.gz
Add support for days and weeks flags
Diffstat (limited to 'distamp.ha')
-rw-r--r--distamp.ha84
1 files changed, 68 insertions, 16 deletions
diff --git a/distamp.ha b/distamp.ha
index f6aa286..9c7de55 100644
--- a/distamp.ha
+++ b/distamp.ha
@@ -3,33 +3,75 @@ use time;
use os;
use strconv;
use strings;
+use getopt;
-type parseerror = strconv::error;
+type parseerror = !strconv::error;
export fn main() void = {
- if (len(os::args) != 2) {
- os::exit(os::status::FAILURE);
+ const cmd = getopt::parse(os::args,
+ "discord relative timestamp generator",
+ ('d', "days", "Number of days"),
+ ('w', "weeks", "Number of weeks"),
+ "m[:s]",
+ );
+ defer getopt::finish(&cmd);
+
+ let days: time::duration = 0;
+ let weeks: time::duration = 0;
+ for (let opt .. cmd.opts) {
+ switch (opt.0) {
+ case 'w' =>
+ weeks = match (toweeks(opt.1)) {
+ case let i: time::duration =>
+ yield i;
+ case let e: strconv::error =>
+ fmt::fatal(strconv::strerror(e));
+ };
+ case 'd' =>
+ days = match (todays(opt.1)) {
+ case let d: time::duration =>
+ yield d;
+ case let e: parseerror =>
+ fmt::fatal(strerror(e));
+ };
+ case => abort();
+ };
};
- let timestr = os::args[1];
- let i = time::now(time::clock::REALTIME);
- let spl = strings::split(timestr, ":");
- defer free(spl);
+ if (len(cmd.args) > 1) {
+ os::exit(os::status::FAILURE);
+ };
- let li = if (len(spl) > 2) {
- fmt::fatal("Duration format: m or m:s");
- } else {
- yield match (parsetime(i, spl)) {
- case let inst: time::instant =>
- yield inst;
- case let e: parseerror =>
- fmt::fatal(strerror(e));
- };
+ let li = match (parsemainargs(cmd.args)) {
+ case let i: time::instant =>
+ yield i;
+ case let e: parseerror =>
+ fmt::fatal(strerror(e));
};
+ li = time::add(li, days);
+ li = time::add(li, weeks);
+
fmt::printfln("<t:{}:R>", time::unix(li))!;
};
+fn parsemainargs(args: []str) (time::instant | parseerror) = {
+ return if (len(args) == 1) {
+ let timestr = args[0];
+ let i = time::now(time::clock::REALTIME);
+ let spl = strings::split(timestr, ":");
+ defer free(spl);
+
+ yield if (len(spl) > 2) {
+ fmt::fatal("Duration format: m or m:s");
+ } else {
+ yield parsetime(i, spl)?;
+ };
+ } else {
+ yield time::now(time::clock::REALTIME);
+ };
+};
+
fn strerror(e: parseerror) str = {
return strconv::strerror(e);
};
@@ -47,3 +89,13 @@ fn parsetime(clk: time::instant, spl: []str) (time::instant | parseerror) = {
};
};
+
+fn todays(days: str) (time::duration | parseerror) = {
+ let d = strconv::stoi(days)?;
+ return d * 24 * time::HOUR;
+};
+
+fn toweeks(weeks: str) (time::duration | parseerror) = {
+ let d = strconv::stoi(weeks)?;
+ return d * 7 * 24 * time::HOUR;
+};