Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/pkl.csv/PklProject
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
amends "../basePklProject.pkl"

package {
version = "1.1.1"
version = "1.1.2"
}
22 changes: 21 additions & 1 deletion packages/pkl.csv/csv.pkl
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,15 @@ class Parser {
(clazz.superclass.ifNonNull((zuper) -> allProps(zuper as reflect.Class)) ?? Map())
+ clazz.properties.filter((_, p) -> !p.modifiers.contains("hidden"))

/// If the input contains no [lineBreak], it is parsed as a single row. A common cause is input that uses `"\n"`
/// with the default `"\r\n"`, which turns empty cells in later lines into "empty header columns".
local _lineBreakHint: String =
if (!input.contains(lineBreak) && input.contains("\n"))
let (escaped = lineBreak.replaceAll("\r", "\\r").replaceAll("\n", "\\n"))
#" The input contains no "\#(escaped)" line breaks, so it was parsed as a single row. If it uses "\n" line breaks, set `lineBreak = "\n"`."#
else
""

local _parsed =
let (self = this)
let (
Expand All @@ -208,7 +217,18 @@ class Parser {
)
let (
header: List<String>? =
(if (includeHeader) stringyResult[0] else properties?.keys)?.toList() as List<String>?
if (includeHeader)
let (headerRow = stringyResult[0])
let (emptyColumn = headerRow.findIndexOrNull((it) -> it == null))
if (emptyColumn == null)
headerRow as List<String>
else
throw(
"Column \(emptyColumn + 1) of the header row is empty, so it can't be used as a column name."
+ _lineBreakHint
)
else
properties?.keys?.toList()
)
if (header == null)
stringyResult.map((rawRow) -> rawRow.toDynamic())
Expand Down
18 changes: 18 additions & 0 deletions packages/pkl.csv/tests/csv_test.pkl
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,24 @@ facts {
}.parsed == homogeneousListing.toList()
}

["Parsing with an empty header column"] {
module.catch(() -> new csv.Parser { input = "A,,C\r\n1,2,3\r\n"; includeHeader = true }.parsed)
== "Column 2 of the header row is empty, so it can't be used as a column name."

// With the default `"\r\n"` line break, `"\n"`-separated input is a single row, so the empty cell ends up in the
// header.
module
.catch(() -> new csv.Parser { input = "A,B,C\n1,,3"; includeHeader = true }.parsed)
.endsWith("If it uses \"\\n\" line breaks, set `lineBreak = \"\\n\"`.")

new csv.Parser {
input = "A,B,C\n1,,3"
includeHeader = true
lineBreak = "\n"
}.parsed
== List(new Dynamic { A = "1"; B = null; C = "3" })
}

["Rendering and parsing CRLF alternatives"] {
for (break in List("\n", "\r", "\t", "😀", "\r\r\n\n")) {
...new Listing {
Expand Down
Loading