gtfs/internal/csv
RFC 4180 compliant CSV parser for GTFS files
This module provides CSV parsing following the GTFS specification:
- UTF-8 encoded (BOM acceptable but ignored)
- Fields may be quoted with double quotes
- Double quotes in fields are escaped as “”
- CRLF or LF line endings are accepted
- First row contains field names (headers)
Source: GTFS reference.md - File Requirements
Types
A parsed CSV row as a dictionary of field names to values
pub type CsvRow =
dict.Dict(String, String)
Errors that can occur during CSV parsing
pub type ParseError {
MissingRequiredField(field: String, row: Int)
InvalidFieldValue(
field: String,
value: String,
expected: String,
row: Int,
)
InvalidRowFormat(row: Int, reason: String)
InvalidUtf8(row: Int)
QuotingError(row: Int, reason: String)
EmptyFile
FieldCountMismatch(row: Int, expected: Int, got: Int)
}
Constructors
-
MissingRequiredField(field: String, row: Int)A required field is missing from the row
-
InvalidFieldValue( field: String, value: String, expected: String, row: Int, )A field value is invalid for its expected type
-
InvalidRowFormat(row: Int, reason: String)The row format is malformed
-
InvalidUtf8(row: Int)Invalid UTF-8 encoding
-
QuotingError(row: Int, reason: String)Quoting error (unclosed quote, etc.)
-
EmptyFileNo header row found
-
FieldCountMismatch(row: Int, expected: Int, got: Int)Mismatched field count
Values
pub fn get_optional(
row: dict.Dict(String, String),
field: String,
) -> option.Option(String)
Get an optional field from a row Returns None if the field is missing or empty
pub fn get_parsed(
row: dict.Dict(String, String),
field: String,
row_num: Int,
parser: fn(String) -> Result(a, String),
) -> Result(option.Option(a), ParseError)
Get a field and parse it with a custom parser
pub fn get_required(
row: dict.Dict(String, String),
field: String,
row_num: Int,
) -> Result(String, ParseError)
Get a required field from a row Returns an error if the field is missing or empty
pub fn get_required_parsed(
row: dict.Dict(String, String),
field: String,
row_num: Int,
parser: fn(String) -> Result(a, String),
) -> Result(a, ParseError)
Get a required field and parse it with a custom parser
pub fn get_with_default(
row: dict.Dict(String, String),
field: String,
default: a,
parser: fn(String) -> Result(a, String),
) -> a
Get a field with a default value if missing or empty
pub fn parse(
content: String,
) -> Result(List(dict.Dict(String, String)), ParseError)
Parse CSV content following RFC 4180 rules Returns a list of rows, each as a dictionary mapping field names to values
pub fn parse_bool(value: String) -> Result(Bool, String)
Parse a boolean (0 = false, 1 = true)
pub fn parse_enum(
value: String,
parser: fn(String) -> Result(a, Nil),
) -> Result(a, String)
Parse an enum value with a mapping function
pub fn parse_non_negative_float(
value: String,
) -> Result(Float, String)
Parse a non-negative float
pub fn parse_non_negative_int(
value: String,
) -> Result(Int, String)
Parse a non-negative integer
pub fn parse_positive_int(value: String) -> Result(Int, String)
Parse a positive integer
pub fn parse_raw(
content: String,
) -> Result(List(List(String)), ParseError)
Parse CSV content and return raw rows (list of field lists) Useful when you need the raw data without header mapping