Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(csv): minor cleanups #5158

Merged
merged 2 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 2 additions & 3 deletions csv/_io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ export async function parseRecord(
const separatorLen = opt.separator.length;
let recordBuffer = "";
const fieldIndexes = [] as number[];
parseField:
for (;;) {
parseField: while (true) {
if (opt.trimLeadingSpace) {
line = line.trimStart();
}
Expand Down Expand Up @@ -118,7 +117,7 @@ export async function parseRecord(
} else {
// Quoted string field
line = line.substring(quoteLen);
for (;;) {
while (true) {
const i = line.indexOf(quote);
if (i >= 0) {
// Hit next quote.
Expand Down
25 changes: 7 additions & 18 deletions csv/csv_stringify_stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,33 +74,22 @@ export class CsvStringifyStream<TOptions extends CsvStringifyStreamOptions>
* @param options Options for the stream.
*/
constructor(options?: TOptions) {
const {
separator,
columns = [],
} = options ?? {};
const { separator, columns = [] } = options ?? {};

super(
{
start(controller) {
if (columns && columns.length > 0) {
try {
controller.enqueue(
stringify([columns], { separator, headers: false }),
);
} catch (error) {
controller.error(error);
}
}
},
transform(chunk, controller) {
try {
controller.enqueue(
stringify([chunk], { separator, headers: false, columns }),
stringify([columns], { separator, headers: false }),
);
} catch (error) {
controller.error(error);
}
},
transform(chunk, controller) {
controller.enqueue(
stringify([chunk], { separator, headers: false, columns }),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, throwing naturally achieves the same result as the previous try/catch block.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

);
},
},
);
}
Expand Down
29 changes: 14 additions & 15 deletions csv/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ class Parser {
const separatorLen = this.#options.separator.length;
let recordBuffer = "";
const fieldIndexes = [] as number[];
parseField:
for (;;) {
parseField: while (true) {
if (this.#options.trimLeadingSpace) {
line = line.trimStart();
}
Expand Down Expand Up @@ -142,7 +141,7 @@ class Parser {
} else {
// Quoted string field
line = line.substring(quoteLen);
for (;;) {
while (true) {
const i = line.indexOf(quote);
if (i >= 0) {
// Hit next quote.
Expand Down Expand Up @@ -250,7 +249,7 @@ class Parser {
throw new Error(ERR_INVALID_DELIM);
}

for (;;) {
while (true) {
const r = this.#parseRecord(lineIndex);
if (r === null) break;
lineResult = r;
Expand Down Expand Up @@ -329,35 +328,35 @@ export function parse(input: string): string[][];
*
* @typeParam T The options' type for parsing.
* @param input The input to parse.
* @param opt The options for parsing.
* @returns If you don't provide `opt.skipFirstRow` and `opt.columns`, it returns `string[][]`.
* If you provide `opt.skipFirstRow` or `opt.columns`, it returns `Record<string, unknown>[]`.
* @param options The options for parsing.
* @returns If you don't provide `options.skipFirstRow` and `options.columns`, it returns `string[][]`.
* If you provide `options.skipFirstRow` or `options.columns`, it returns `Record<string, unknown>[]`.
*/
export function parse<const T extends ParseOptions>(
input: string,
opt: T,
options: T,
): ParseResult<ParseOptions, T>;
export function parse<const T extends ParseOptions>(
input: string,
opt: T = { skipFirstRow: false } as T,
options: T = { skipFirstRow: false } as T,
): ParseResult<ParseOptions, T> {
const parser = new Parser(opt);
const parser = new Parser(options);
const r = parser.parse(input);

if (opt.skipFirstRow || opt.columns) {
if (options.skipFirstRow || options.columns) {
let headers: readonly string[] = [];

if (opt.skipFirstRow) {
if (options.skipFirstRow) {
const head = r.shift();
if (head === undefined) throw new TypeError("Headers must be defined");
headers = head;
}

if (opt.columns) {
headers = opt.columns;
if (options.columns) {
headers = options.columns;
}

const firstLineIndex = opt.skipFirstRow ? 1 : 0;
const firstLineIndex = options.skipFirstRow ? 1 : 0;
return r.map((row, i) => {
return convertRowToObject(row, headers, firstLineIndex + i);
}) as ParseResult<ParseOptions, T>;
Expand Down
10 changes: 7 additions & 3 deletions csv/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ export type StringifyOptions = {
*/
separator?: string;
/**
* a list of instructions for how to target and transform the data for each
* A list of instructions for how to target and transform the data for each
* column of output. This is also where you can provide an explicit header
* name for the column.
*
* @default {[]}
*/
columns?: Column[];
/**
Expand Down Expand Up @@ -299,9 +301,11 @@ function getValuesFromItem(
*/
export function stringify(
data: DataItem[],
{ headers = true, separator: sep = ",", columns = [], bom = false }:
StringifyOptions = {},
options?: StringifyOptions,
): string {
const { headers = true, separator: sep = ",", columns = [], bom = false } =
options ?? {};

if (sep.includes(QUOTE) || sep.includes(CRLF)) {
const message = [
"Separator cannot include the following strings:",
Expand Down
Loading