M +test.ha => +test.ha +12 -1
@@ 2,13 2,24 @@ use io;
use memio;
use os;
-const lines = [
+const lines: []str = [
"alice : Alice Z. <alice@harelang.org>",
"bob : Robert Y. <robert@harelang.org>",
"carol : <carol@sourehut.org>",
"Dan <daniel@sourcehut.org>",
];
+@test fn key_exists() void = {
+ assert(key_exists("alice", lines));
+ assert(!key_exists("ali", lines));
+ assert(!key_exists("Dan", lines));
+};
+
+@test fn add() void = {
+ assert(!add("bob", "Robert X.", &lines[..]));
+ assert(add("rob", "Robert Y. <robert@harelang.org>", &lines[..]));
+};
+
@test fn check_alias() void = {
assert(check_alias("john", "john : <john@xxx>") as str == "<john@xxx>");
assert(check_alias("jo", "john : <john@xxx>") as str == "<john@xxx>");
M README.md => README.md +2 -4
@@ 1,9 1,7 @@
-# emailbook-janet
+# emailbook-hare
A minimalistic address book for e-mails only.
-⚠ **WORK IN PROGRESS!** Not everything decribed in this README is implemented yet.
-
## Installation
Install [Hare](https://harelang.org) if necessary.
@@ 15,7 13,7 @@ git clone https://git.sr.ht/~maxgyver83/emailbook-hare
```
If don't have Hare installed and really don't want to install it,
-simply download this binary (for Linux, x86-64), about 440 kB (TODO: Add link).
+simply download this binary (for Linux, x86-64), about 470 kB (TODO: Add link).
If you like, copy `emailbook-hare` to a directory which is
in your `PATH` (p.e. `$HOME/.local/bin/` or `/usr/local/bin/`). (Otherwise, use
M emailbook-hare.ha => emailbook-hare.ha +33 -2
@@ 10,7 10,7 @@ use regex;
use strconv;
use strings;
-def version = "0.0.1";
+def version = "0.1.0";
def max_header_size = 20000z; // bytes
let emailbook_file: io::file = 0;
@@ 47,6 47,34 @@ Options:
os::exit(0);
};
+fn key_exists(key: str, lines: []str) bool = {
+ for (let line .. lines) {
+ if (strings::hasprefix(line, strings::concat(key, " :")))
+ return true;
+ };
+ return false;
+};
+
+fn add(key: (str | void), value: str, lines: *[]str) bool = {
+ const exists: bool = match (key) {
+ case let k: str =>
+ yield key_exists(k, *lines);
+ case void =>
+ yield mailbox_in_list(value, lines)
+ || mailbox_in_list(toggle_quotes(value), lines);
+ };
+ if (exists) {
+ fmt::printfln("! {} (skipped)", if (key is str) key else value)!;
+ return false;
+ };
+ const line = if (key is str) strings::concat(key as str, " : ", value) else value;
+ fmt::printfln("+ {}", line)!;
+ append(lines, strings::dup(line));
+ io::write(emailbook_file, strings::toutf8(line))!;
+ io::write(emailbook_file, ['\n'])!;
+ return true;
+};
+
fn check_alias(query_lower: str, line: str) (str | void) = {
const pos_colon = match (strings::index(line, ":")) {
case void =>
@@ 348,7 376,8 @@ fn match_mailbox(line: str, mailboxes: *[]str) void = {
match (result) {
case let i: size =>
if (i > 0 && bytes[i - 1] != ' ') {
- line = strings::concat(strings::fromutf8_unsafe(bytes[..i]), " ", strings::fromutf8_unsafe(bytes[i..]));
+ line = strings::concat(strings::fromutf8_unsafe(bytes[..i]),
+ " ", strings::fromutf8_unsafe(bytes[i..]));
};
case void => void;
};
@@ 525,8 554,10 @@ export fn main() void = {
if (len(os::args) == 5) {
const key = os::args[3];
const value = os::args[4];
+ add(key, value, &lines);
} else {
const value = os::args[3];
+ add(void, value, &lines);
};
case "-k", "--key" =>
const query = os::args[3];