Skip to content

Commit

Permalink
refactor(csv): minor cleanups (#5158)
Browse files Browse the repository at this point in the history
* refactor(csv): minor cleanups

* fix
  • Loading branch information
iuioiua committed Jun 27, 2024
1 parent c8a8859 commit 506439a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 39 deletions.
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 }),
);
},
},
);
}
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
11 changes: 8 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 @@ -295,13 +297,16 @@ function getValuesFromItem(
*
* @param data The source data to stringify. It's an array of items which are
* plain objects or arrays.
* @param options Options for the stringification.
* @returns A CSV string.
*/
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

0 comments on commit 506439a

Please sign in to comment.