docs(csv): complete documentation (#4163)

This commit is contained in:
Asher Gomez 2024-01-11 17:02:30 +11:00 committed by GitHub
parent f5b6774dcd
commit b1aeecfadd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 25 deletions

View File

@ -5,6 +5,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assert } from "../assert/assert.ts";
/** Options for {@linkcode parseRecord}. */
export interface ReadOptions {
/** Character which separates values.
*
@ -223,6 +224,7 @@ export class ParseError extends SyntaxError {
/** Column (rune index) where the error occurred */
column: number | null;
/** Constructs a new instance. */
constructor(
start: number,
line: number,
@ -268,22 +270,30 @@ export function convertRowToObject(
return out;
}
// deno-fmt-ignore
/** Options for {@linkcode parse} and {@linkcode CsvParseStream}. */
export type ParseResult<ParseOptions, T> =
// If `columns` option is specified, the return type is Record type.
T extends ParseOptions & { columns: readonly (infer C extends string)[] }
? RecordWithColumn<C>[]
// If `skipFirstRow` option is specified, the return type is Record type.
: T extends ParseOptions & { skipFirstRow: true }
? Record<string, string | undefined>[]
// If `columns` and `skipFirstRow` option is _not_ specified, the return type is string[][].
: T extends ParseOptions & { columns?: undefined; skipFirstRow?: false | undefined }
? string[][]
// else, the return type is Record type or string[][].
: Record<string, string | undefined>[] | string[][];
// If `skipFirstRow` option is specified, the return type is Record type.
: T extends ParseOptions & { skipFirstRow: true }
? Record<string, string | undefined>[]
// If `columns` and `skipFirstRow` option is _not_ specified, the return type is string[][].
: T extends
ParseOptions & { columns?: undefined; skipFirstRow?: false | undefined }
? string[][]
// else, the return type is Record type or string[][].
: Record<string, string | undefined>[] | string[][];
// RecordWithColumn<"aaa"|"bbb"> => Record<"aaa"|"bbb", string>
// RecordWithColumn<string> => Record<string, string | undefined>
type RecordWithColumn<C extends string> = string extends C
/**
* Record type with column type.
*
* @example
* ```
* type RecordWithColumn<"aaa"|"bbb"> => Record<"aaa"|"bbb", string>
* type RecordWithColumn<string> => Record<string, string | undefined>
* ```
*/
export type RecordWithColumn<C extends string> = string extends C
? Record<string, string | undefined>
: Record<C, string>;

View File

@ -11,6 +11,7 @@ import {
} from "../csv/_io.ts";
import { TextDelimiterStream } from "../streams/text_delimiter_stream.ts";
/** Options for {@linkcode CsvParseStream}. */
export interface CsvParseStreamOptions extends ReadOptions {
/**
* If you provide `skipFirstRow: true` and `columns`, the first line will be
@ -54,15 +55,16 @@ function stripLastCR(s: string): string {
return s.endsWith("\r") ? s.slice(0, -1) : s;
}
type RowType<T> = T extends undefined ? string[]
/** Row return type. */
export type RowType<T> = T extends undefined ? string[]
: ParseResult<CsvParseStreamOptions, T>[number];
/**
* Read data from a CSV-encoded stream or file.
* Provides an auto/custom mapper for columns.
* Read data from a CSV-encoded stream or file. Provides an auto/custom mapper
* for columns.
*
* A `CsvParseStream` expects input conforming to
* [RFC 4180](https://rfc-editor.org/rfc/rfc4180.html).
* {@link https://tools.ietf.org/html/rfc4180 | RFC 4180}.
*
* @example
* ```ts
@ -87,6 +89,7 @@ export class CsvParseStream<
#headers: readonly string[] = [];
/** Construct a new instance. */
constructor(options?: T) {
this.#options = {
...defaultReadOptions,
@ -167,10 +170,12 @@ export class CsvParseStream<
}
}
/** The instance's {@linkcode ReadableStream}. */
get readable(): ReadableStream<RowType<T>> {
return this.#readable as ReadableStream<RowType<T>>;
}
/** The instance's {@linkcode WritableStream}. */
get writable(): WritableStream<string> {
return this.#lines.writable;
}

View File

@ -1,6 +1,7 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { stringify } from "./stringify.ts";
/** Options for {@linkcode CsvStringifyStream}. */
export interface CsvStringifyStreamOptions {
/**
* Delimiter used to separate values.
@ -43,6 +44,7 @@ export class CsvStringifyStream<TOptions extends CsvStringifyStreamOptions>
: Array<unknown>,
string
> {
/** Construct a new instance. */
constructor(options?: TOptions) {
const {
separator,

View File

@ -4,7 +4,7 @@
/** Reads and writes comma-separated values (CSV) files.
*
* There are many kinds of CSV files; this module supports the format described
* in [RFC 4180](https://www.rfc-editor.org/rfc/rfc4180.html).
* in {@link https://tools.ietf.org/html/rfc4180 | RFC 4180}.
*
* A csv file contains zero or more records of one or more fields per record.
* Each record is separated by the newline character. The final record may

View File

@ -10,10 +10,11 @@ import {
ParseError,
type ParseResult,
type ReadOptions,
type RecordWithColumn,
} from "./_io.ts";
import { assert } from "../assert/assert.ts";
export { ParseError, type ParseResult, ReadOptions };
export { ParseError, type ParseResult, ReadOptions, type RecordWithColumn };
const BYTE_ORDER_MARK = "\ufeff";
@ -280,6 +281,7 @@ class Parser {
}
}
/** Options for {@linkcode parse}. */
export interface ParseOptions extends ReadOptions {
/**
* If you provide `skipFirstRow: true` and `columns`, the first line will be
@ -317,6 +319,29 @@ export interface ParseOptions extends ReadOptions {
* If you provide `opt.skipFirstRow` or `opt.columns`, it returns `Record<string, unknown>[]`.
*/
export function parse(input: string, opt?: undefined): string[][];
/**
* Csv parse helper to manipulate data.
* Provides an auto/custom mapper for columns.
*
* @example
* ```ts
* import { parse } from "https://deno.land/std@$STD_VERSION/csv/parse.ts";
* const string = "a,b,c\nd,e,f";
*
* console.log(
* await parse(string, {
* skipFirstRow: false,
* }),
* );
* // output:
* // [["a", "b", "c"], ["d", "e", "f"]]
* ```
*
* @param input Input to parse.
* @param opt options of the parser.
* @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>[]`.
*/
export function parse<const T extends ParseOptions>(
input: string,
opt: T,

View File

@ -1,10 +1,12 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
type PropertyAccessor = number | string;
type ObjectWithStringPropertyKeys = Record<string, unknown>;
/** Array index or record key corresponding to a value for a data object. */
export type PropertyAccessor = number | string;
/**
* Column information.
*
* @param header Explicit column header name. If omitted,
* the (final) property accessor is used for this value.
*
@ -82,8 +84,9 @@ export type ColumnDetails = {
export type Column = ColumnDetails | PropertyAccessor | PropertyAccessor[];
/** An object (plain or array) */
export type DataItem = ObjectWithStringPropertyKeys | unknown[];
export type DataItem = Record<string, unknown> | unknown[];
/** Options for {@linkcode stringify}. */
export type StringifyOptions = {
/** Whether to include the row of headers or not.
*
@ -165,8 +168,13 @@ function normalizeColumn(column: Column): NormalizedColumn {
return { header, prop };
}
/** Error thrown in {@linkcode stringify}. */
export class StringifyError extends Error {
override readonly name = "StringifyError";
/** Construct a new instance. */
constructor(message?: string) {
super(message);
this.name = "StringifyError";
}
}
/**
@ -193,7 +201,7 @@ function getValuesFromItem(
);
}
} // I think this assertion is safe. Confirm?
else value = (value as ObjectWithStringPropertyKeys)[prop];
else value = (value as Record<string, unknown>)[prop];
}
values.push(value);
@ -273,8 +281,6 @@ function getValuesFromItem(
* // Rick,70
* // Morty,14
* ```
*
* @param options Output formatting options
*/
export function stringify(
data: DataItem[],