use fmt; use dirs; use bufio; use os; use fs; use path; use io; use strings; use format::ini; type task = struct { name: str, context: (str | void), tags: ([]str | void), priority: uint, }; def METADATASEP: str = "----"; fn listtasks(root: str = "tasks", context: str = "*") ([]task | fs::error | path::error) = { const dirents = os::readdir(root)?; defer fs::dirents_free(dirents); let tasks: []task = []; for (const dirent .. dirents) { if (context == "*" || dirent.name == context) { if (fs::isdir(dirent.ftype)) { let buf = path::init()?; const p = path::push(&buf, root, dirent.name)?; listtasks(p)?; } else { fmt::println(dirent.name)!; }; }; }; return tasks; }; fn readtask(taskpath: str) (task | fs::error) = { const f = os::open(taskpath)?; defer io::close(f)!; const sc = bufio::newscanner(f); defer bufio::finish(&sc); for (let line => bufio::scan_line(&sc)?) { line = strings::trim(line); if (line == METADATASEP) { break; }; }; }; export fn main() void = { match (listtasks()) { case let e: fs::error => fmt::fatal(fs::strerror(e)); case let e: path::error => fmt::fatal(path::strerror(e)); case => void; }; };