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 BufReader/BufWriter interfaces to be more idiomatic #444

Merged
merged 1 commit into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
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
47 changes: 18 additions & 29 deletions encoding/csv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// https://github.com/golang/go/blob/go1.12.5/src/encoding/csv/
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.

import { BufReader, BufState } from "../io/bufio.ts";
import { BufReader, EOF } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts";

const INVALID_RUNE = ["\r", "\n", '"'];
Expand All @@ -25,30 +25,29 @@ export interface ParseOptions {
fieldsPerRecord?: number;
}

function chkOptions(opt: ParseOptions): Error | null {
function chkOptions(opt: ParseOptions): void {
if (
INVALID_RUNE.includes(opt.comma) ||
INVALID_RUNE.includes(opt.comment) ||
opt.comma === opt.comment
) {
return Error("Invalid Delimiter");
throw new Error("Invalid Delimiter");
}
return null;
}

export async function read(
Startline: number,
reader: BufReader,
opt: ParseOptions = { comma: ",", comment: "#", trimLeadingSpace: false }
): Promise<[string[], BufState]> {
): Promise<string[] | EOF> {
const tp = new TextProtoReader(reader);
let err: BufState;
let line: string;
let result: string[] = [];
let lineIndex = Startline;

[line, err] = await tp.readLine();

const r = await tp.readLine();
if (r === EOF) return EOF;
line = r;
// Normalize \r\n to \n on all input lines.
if (
line.length >= 2 &&
Expand All @@ -61,12 +60,12 @@ export async function read(

const trimmedLine = line.trimLeft();
if (trimmedLine.length === 0) {
return [[], err];
return [];
}

// line starting with comment character is ignored
if (opt.comment && trimmedLine[0] === opt.comment) {
return [result, err];
return [];
}

result = line.split(opt.comma);
Expand All @@ -92,12 +91,9 @@ export async function read(
}
);
if (quoteError) {
return [
[],
new ParseError(Startline, lineIndex, 'bare " in non-quoted-field')
];
throw new ParseError(Startline, lineIndex, 'bare " in non-quoted-field');
}
return [result, err];
return result;
}

export async function readAll(
Expand All @@ -107,19 +103,18 @@ export async function readAll(
trimLeadingSpace: false,
lazyQuotes: false
}
): Promise<[string[][], BufState]> {
): Promise<string[][]> {
const result: string[][] = [];
let _nbFields: number;
let err: BufState;
let lineResult: string[];
let first = true;
let lineIndex = 0;
err = chkOptions(opt);
if (err) return [result, err];
chkOptions(opt);

for (;;) {
[lineResult, err] = await read(lineIndex, reader, opt);
if (err) break;
const r = await read(lineIndex, reader, opt);
if (r === EOF) break;
lineResult = r;
lineIndex++;
// If fieldsPerRecord is 0, Read sets it to
// the number of fields in the first record
Expand All @@ -136,16 +131,10 @@ export async function readAll(

if (lineResult.length > 0) {
if (_nbFields && _nbFields !== lineResult.length) {
return [
null,
new ParseError(lineIndex, lineIndex, "wrong number of fields")
];
throw new ParseError(lineIndex, lineIndex, "wrong number of fields");
}
result.push(lineResult);
}
}
if (err !== "EOF") {
return [result, err];
}
return [result, null];
return result;
}
35 changes: 23 additions & 12 deletions encoding/csv_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,20 +437,31 @@ for (const t of testCases) {
if (t.LazyQuotes) {
lazyquote = t.LazyQuotes;
}
const actual = await readAll(new BufReader(new StringReader(t.Input)), {
comma: comma,
comment: comment,
trimLeadingSpace: trim,
fieldsPerRecord: fieldsPerRec,
lazyQuotes: lazyquote
});
let actual;
if (t.Error) {
assert(!!actual[1]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const e: any = actual[1];
assertEquals(e.message, t.Error);
let err;
try {
actual = await readAll(new BufReader(new StringReader(t.Input)), {
comma: comma,
comment: comment,
trimLeadingSpace: trim,
fieldsPerRecord: fieldsPerRec,
lazyQuotes: lazyquote
});
} catch (e) {
err = e;
}
assert(err);
assertEquals(err.message, t.Error);
} else {
const expected = [t.Output, null];
actual = await readAll(new BufReader(new StringReader(t.Input)), {
comma: comma,
comment: comment,
trimLeadingSpace: trim,
fieldsPerRecord: fieldsPerRec,
lazyQuotes: lazyquote
});
const expected = t.Output;
assertEquals(actual, expected);
}
}
Expand Down
8 changes: 4 additions & 4 deletions http/file_server_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { readFile, run } = Deno;

import { test } from "../testing/mod.ts";
import { assert, assertEquals } from "../testing/asserts.ts";
import { BufReader } from "../io/bufio.ts";
import { BufReader, EOF } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts";

let fileServer;
Expand All @@ -22,10 +22,10 @@ async function startFileServer(): Promise<void> {
});
// Once fileServer is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(fileServer.stdout));
const [s, err] = await r.readLine();
assert(err == null);
assert(s.includes("server listening"));
const s = await r.readLine();
assert(s !== EOF && s.includes("server listening"));
}

function killFileServer(): void {
fileServer.close();
fileServer.stdout.close();
Expand Down
14 changes: 7 additions & 7 deletions http/racing_server_test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const { dial, run } = Deno;

import { test } from "../testing/mod.ts";
import { test, runIfMain } from "../testing/mod.ts";
import { assert, assertEquals } from "../testing/asserts.ts";
import { BufReader } from "../io/bufio.ts";
import { BufReader, EOF } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts";

let server;
Expand All @@ -13,9 +13,8 @@ async function startServer(): Promise<void> {
});
// Once fileServer is ready it will write to its stdout.
const r = new TextProtoReader(new BufReader(server.stdout));
const [s, err] = await r.readLine();
assert(err == null);
assert(s.includes("Racing server listening..."));
const s = await r.readLine();
assert(s !== EOF && s.includes("Racing server listening..."));
}
function killServer(): void {
server.close();
Expand Down Expand Up @@ -57,9 +56,10 @@ test(async function serverPipelineRace(): Promise<void> {
const outLines = output.split("\n");
// length - 1 to disregard last empty line
for (let i = 0; i < outLines.length - 1; i++) {
const [s, err] = await r.readLine();
assert(!err);
const s = await r.readLine();
assertEquals(s, outLines[i]);
}
killServer();
});

runIfMain(import.meta);
Loading