use io; use strings; use fmt; use memio; // Writes a slice strings to a handle in TSV format. Existing tabs in the record // are removed. export fn writerecord(w: io::handle, record: []str) (void | io::error) = { let sep = ""; for (const field .. record) { const pfield = strings::replace(field, "\t", ""); defer free(pfield); fmt::fprintf(w, "{}{}", sep, pfield)!; sep = "\t"; }; fmt::fprintln(w)!; }; // Writes a slice of string slices to a handle in TSV format. Existing tabs in // the records are removed. export fn writerecords(w: io::handle, records: [][]str) (void | io::error) = { for (const record .. records) { writerecord(w, record)?; }; }; @test fn writenormal() void = { const expected = "col1\tcol2\tcol3 1\t2\t3 4\t5\t6\n"; const input: [][]str = [ ["col1", "col2", "col3"], ["1", "2", "3"], ["4", "5", "6"], ]; const st = memio::dynamic(); defer io::close(&st)!; writerecords(&st, input)!; const actual = memio::string(&st)!; fmt::errorfln("expected: {}EOF", expected)!; fmt::errorln()!; fmt::errorfln("actual: {}EOF", actual)!; assert(actual == expected); }; @test fn writetabs() void = { const expected = "col1\tcol2\tcol3 1\t2\t3 4\t5\t6\n"; const input: [][]str = [ ["col1\t", "co\tl2", "col3"], ["1", "2", "\t3"], ["4\t", "\t\t5\t", "6"], ]; const st = memio::dynamic(); defer io::close(&st)!; writerecords(&st, input)!; const actual = memio::string(&st)!; fmt::errorfln("expected: {}EOF", expected)!; fmt::errorln()!; fmt::errorfln("actual: {}EOF", actual)!; assert(actual == expected); };