AshCsvInterchange.Import.Parser (AshCsvInterchange v0.1.0)

Copy Markdown View Source

RFC 4180 CSV parser with an eager path and a streaming path.

parse/1 parses a whole binary into a list of rows. parse_stream/2 reads only the header line eagerly, so fatal header and encoding errors surface at once, and returns the data rows as a lazy stream over NimbleCSV.RFC4180.parse_stream/2.

A streaming source is a binary, a {:path, path} tuple (the parser opens the file), or any re-enumerable Enumerable of binary chunks. One-shot sources do not work: reading the header enumerates the source once, and the body enumerates it again.

Summary

Functions

Parses a CSV binary into a list of row lists. Returns a fatal error for invalid UTF-8 or malformed CSV (e.g. unterminated quotes).

Reads the header line eagerly and returns the data rows as a lazy stream.

Types

source()

@type source() :: binary() | {:path, Path.t()} | Enumerable.t()

Functions

parse(binary)

@spec parse(binary()) :: {:ok, [[String.t()]]} | {:error, AshCsvInterchange.Error.t()}

Parses a CSV binary into a list of row lists. Returns a fatal error for invalid UTF-8 or malformed CSV (e.g. unterminated quotes).

parse_stream(source, headers_config)

@spec parse_stream(source(), keyword()) ::
  {:ok, {[String.t()], Enumerable.t()}} | {:error, AshCsvInterchange.Error.t()}

Reads the header line eagerly and returns the data rows as a lazy stream.

Returns {:ok, {header_row, body}}. header_row is a list of column strings. body is a lazy Enumerable of data rows, each a list of strings, with the header excluded. Returns {:error, %Error{}} for an empty file or a malformed header line.

Invalid UTF-8 in a data row is not detected here. It raises StreamError, this module's nested exception, when the body stream is consumed.