From e2bee01af84bc7a6bc191f931f195b3c0b5175cc Mon Sep 17 00:00:00 2001 From: Julian Hurst Date: Fri, 15 Nov 2024 01:14:07 +0100 Subject: Add csv command --- cmd.ha | 20 ++++++++++++++++++++ csv/csv.ha | 30 ++++++++++++++++++++++++++++++ hatask.ha | 2 ++ 3 files changed, 52 insertions(+) create mode 100644 csv/csv.ha diff --git a/cmd.ha b/cmd.ha index dd4afc1..6924fa9 100644 --- a/cmd.ha +++ b/cmd.ha @@ -7,6 +7,7 @@ use path; use os::exec; use strconv; use ascii; +use csv; type error = !(!str | io::error | path::error | exec::error | strconv::error); @@ -38,6 +39,10 @@ const commands: [_]command = [ names = ["d", "done"], func = &do, }, + command { + names = ["c", "csv"], + func = &csv, + }, ]; fn execcommand(name: str, tasks: []task, args: arguments) (void | error) = { @@ -78,6 +83,13 @@ fn show(tasks: []task, a: arguments) (void | task | error) = { fmt::println(t.content)!; }; +fn printtaskcsv(t: task, id: size) (void | error) = { + const sid = strings::dup(strconv::ztos(id)); + defer free(sid); + const spriority = strconv::ztos(t.priority); + csv::writerecord(os::stdout, [sid, t.name, spriority])!; +}; + fn printtask(t: task, id: size) (void | error) = { let name = strings::dup(t.name); defer free(name); @@ -143,6 +155,14 @@ fn filter(tasks: []task, a: arguments) (void | task | error) = { }; }; +fn csv(tasks: []task, a: arguments) (void | task | error) = { + csv::writerecord(os::stdout, ["id" ,"name", "priority"])!; + for (let i = 0z; i < len(tasks); i += 1) { + const t = tasks[i]; + printtaskcsv(t, i)?; + }; +}; + fn listall(tasks: []task) void = { const headpad = PADDING - len("name") + len("priority"); const namepad = 10 - len("id") + len("name"); diff --git a/csv/csv.ha b/csv/csv.ha new file mode 100644 index 0000000..40e1e3b --- /dev/null +++ b/csv/csv.ha @@ -0,0 +1,30 @@ +use io; +use strings; +use fmt; + +export type error = !(str | io::error); + +export fn writerecord(w: io::handle, record: []str, separator: const str = ",", quote: const rune = + '"') (void | error) = { + let sep = ""; + for (const field .. record) { + if (strings::contains(field, separator)) { + if (strings::contains(field, quote)) { + return "ERROR: Field contains quote character + (not supported)"; + }; + fmt::fprintf(w, "{}{}{}{}", sep, quote, field, quote)!; + } else { + fmt::fprintf(w, "{}{}", sep, field)!; + }; + sep = separator; + }; + fmt::fprintln(w)!; +}; + +export fn writerecords(w: io::handle, records: [][]str, separator: const str = ",", quote: const + rune = '"') (void | error) = { + for (const record .. records) { + writerecord(w, record, separator, quote)?; + }; +}; diff --git a/hatask.ha b/hatask.ha index 33aeb2e..190f82b 100644 --- a/hatask.ha +++ b/hatask.ha @@ -130,6 +130,8 @@ export fn main() void = { ("w", ["write a task", "id"]: []getopt::help), ("done", ["delete a task", "id"]: []getopt::help), ("d", ["delete a task", "id"]: []getopt::help), + ("csv", ["print csv of tasks"]: []getopt::help), + ("c", ["print csv of tasks"]: []getopt::help), ); defer getopt::finish(&cmd); -- cgit v1.2.3