A CSV library for Zig.
Zarko provides a simple way to parse and write CSVs while supporting configurable dialects, records, quoting, and line endings.
- Parse CSV data from memory
- Write CSV files
- Support quoted fields
- Handle escaped quotes
- Borrow field data directly from the input when possible
- Configure CSV dialect options
- Field separators
- Quote characters
- Line endings
Add Zarko as a dependency in your build.zig.zon using the following command:
zig fetch --save https://github.com/TynK-M/zarko/archive/HEAD.tar.gzThen add it as a dependency in your build.zig.zon:
const zarko_dep = b.dependency("zarko", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("zarko", zarko_dep.module("zarko"));And, finally, import it in your Zig code:
const zarko = @import("zarko");Import Zarko and create a parser with your CSV input.
const csv =
\\name,age,city
\\Matteo,22,Rome
\\Linus,56,Helsinki
\\Ada,"36",London
\\QuoteTest,"312","Hello, ""World!"""
;
var arena = std.heap.ArenaAllocator.init(
std.heap.page_allocator,
);
defer arena.deinit();
var parser = zarko.Parser.init(arena.allocator(), csv, .{});
while (try parser.next()) |record| {
for (record.fields) |field| {
std.debug.print("{s} ", .{field});
}
std.debug.print("\n", .{});
}Quoted fields are unwrapped and escaped quotes are unescaped:
"Hello, ""World!"""
becomes:
Hello, "World!"
Zarko offers pre-created examples under the examples folder, to run them use:
zig build run-<example-name>The existing example names are:
| Name | Corresponding file |
|---|---|
| parser | examples/parser.zig |
| file-parser | examples/file_parser.zig |
| file-writer | examples/file_writer.zig |
Zarko does not own the input CSV data. The input slice must remain valid as long as any parser record contains fields borrowed from it.
Each parsed Record owns its field slice and any field data that had to be allocated while parsing, such as fields containing escaped quotes.
Records must be deinitialized when they are no longer needed:
var record = (try parser.next()).?;
defer record.deinit(allocator);Fields that do not require allocation borrow directly from the input. Fields that require quote unescaping are allocated using the allocator provided to the parser and are owned by the corresponding Record.
var first = (try parser.next()).?;
defer first.deinit(allocator);
var second = (try parser.next()).?;
defer second.deinit(allocator);The parser does not own previously returned records.
CSV formats are not always identical. Zarko allows customizing parsing rules through Dialect.
const dialect = zarko.Dialect{
.separator = ';',
.quote = '"',
.line_ending = .lf,
};For example, this can be used to parse semicolon-separated data:
name;age;city
Matteo;22;Rome
Every contribution is welcome, for more informations regarding contributions refer to contributing.
See the MIT License for details.