User mw in the forums stumbled upon this issue:
https://forum.dlang.org/thread/[email protected]
The user's use case and verdict:
"We have a class/struct for a data record, some of its data fields need to be saved/loaded from CSV files; while there are other helper fields which are useful for various computation tasks (e.g. caching some intermediate computation results), these fields do not need to be saved/loaded from the csv files.
A CSV library should consider all the use cases, and allow users to ignore certain fields."
Docs say:
"An optional header can be provided. The first record will be read in as the header. If Contents is a struct then the header provided is expected to correspond to the fields in the struct."
But this is never enforced and just fails with index error as seen in this slightly modified docs example:
---
import std.algorithm.comparison : equal;
string text = "a,b,c\nHello,65,2.5\nWorld,123,7.5";
struct Layout
{
int value;
double other;
string name;
bool ok; // added, now 4 fields, but header.length == 3
}
auto records = text.csvReader!Layout(["b","c","a"]);
assert(records.equal([
Layout(65, 2.5, "Hello"),
Layout(123, 7.5, "World")
]));
---
Error:
core.exception.ArrayIndexError@/dlang/dmd/linux/bin64/../../src/phobos/std/csv.d(1209): index [3] is out of bounds for array of length 3
Where it fails:
https://github.com/dlang/phobos/blob/8e8aaae5080ccc2e0a2202cbe9778dca96496a95/std/csv.d#L1209
This needs, should the impl remain the same, a nicer assert error message in the constructer enforcing that content's field count is not higher than colHeaders.length.
Comment #1 by Jesse.K.Phillips+D — 2022-10-05T04:01:35Z
I think you're probably right, but what about
class Layout
{
int value;
double other;
string name;
}
struct Cache {
Layout data;
alias data this;
int extra_field; // un-comment to see the error
static Cache opCall(Layout d) {
Cache c;
c.data = d;
return c;
}
}
void main()
{
import std.csv;
import std.stdio: write, writeln, writef, writefln;
import std.algorithm.comparison : equal;
import std.algorithm : map;
string text = "a,b,c\nHello,65,2.5\nWorld,123,7.5";
auto records =
text.csvReader!Layout(["b","c","a"])
.map!(x => Cache(x)) ; // Read only these column
foreach (r; records) writeln(r.name);
}
Comment #2 by robert.schadek — 2024-12-01T16:40:27Z