// 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;<plain> 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)
}
The file itself · all the examples