// Reads a stock list and writes it as an HTML page, largest count first, // from three files: this one, `stock.nika` (the parse) and `page.nika` (the page). // // printf 'tools;Bolts & Nuts;12\npaper; A4;40\n' > stock.csv // nikaia run -- stock.csv report.html // 2 items, 52 in total // // Shows: one package in several files, and `pub`. // // A package: `nikaia run` in this directory runs it, and `nikaia test` checks what // it prints and the page it writes against `tests/` (ADR-247), and runs the test // at the end of this file. // // A package is a directory, and its files share one namespace. So there is no // `use` between them: `read`, `total` and `render` are simply called here. // `pub` means visible outside the package, not outside the file. use std::fs use std::cli fn main() throws { let path = cli::args().nth(1) ?? "stock.csv" let out = cli::args().nth(2) ?? "report.html" let data = fs::map(ref path, fs::Root::Anywhere) catch { eprintln(f"cannot open {path}: {error}") return } let mut entries = read(data.text()) catch { eprintln(f"{path}: {error}") return } entries.sort_by_key fn (entry) { -entry.count } let total = total(entries) let count = entries.len() let markup = render(entries, total) fs::write(ref out, fs::Root::Anywhere, ref markup) catch { eprintln(f"cannot write {out}: {error}") return } println(f"{count} items, {total} in total") } // **A test writes under a root of its own** (ADR-247 D5): `fs::scratch()` is a // fresh directory, removed when the test ends, and the page goes under it the // way `main` writes it anywhere. test "the page escapes the stock file, and is written as it was made" { let entries = read("tools;Bolts & Nuts;12\n") let page = render(entries, 12) assert(page.contains("Bolts & Nuts")) let root = fs::scratch() fs::write("page.html", root, ref page) let back = fs::read_to_string("page.html", root) assert(back == page) }