mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
docs(csv): complete documentation (#4163)
This commit is contained in:
parent
f5b6774dcd
commit
b1aeecfadd
34
csv/_io.ts
34
csv/_io.ts
@ -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>;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
27
csv/parse.ts
27
csv/parse.ts
@ -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,
|
||||
|
@ -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[],
|
||||
|
Loading…
Reference in New Issue
Block a user