Skip to content

Commit dfcd316

Browse files
committed
feat(quoted_string): add isQdtext function
1 parent a2b87b9 commit dfcd316

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,28 @@ assert(isTchar("*!~"));
582582
assertFalse(isToken(""));
583583
```
584584

585+
## Quoted Strings
586+
587+
Compliant with
588+
[RFC 9110, 5.6.4. Quoted Strings](https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.4).
589+
590+
### isQdtext
591+
592+
Whether the input is
593+
[qdtext](https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.4-2) or not.
594+
595+
```ts
596+
import { isQdtext } from "https://deno.land/x/http_utils@$VERSION/quoted_string.ts";
597+
import {
598+
assert,
599+
assertFalse,
600+
} from "https://deno.land/std@$VERSION/testing/asserts.ts";
601+
602+
assert(isQdtext("\t"));
603+
assert(isQdtext("\xFF"));
604+
assertFalse(isQdtext(`"`));
605+
```
606+
585607
## License
586608

587609
Copyright © 2023-present [httpland](https://github.com/httpland).

quoted_string.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
2+
// This module is browser compatible.
3+
4+
// export function isQuotedString(input: string): input is QuotedString {
5+
// }
6+
7+
/**
8+
* ```abnf
9+
* obs-text = %x80-FF
10+
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
11+
* ```
12+
*/
13+
const reQdtext = /^[\t \x21\x23-\x5B\x5D-\x7E\x80-\xFF]$/;
14+
15+
/** Whether the input is [qdtext](https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.4-2) or not.
16+
*
17+
* @example
18+
* ```ts
19+
* import { isQdtext } from "https://deno.land/x/http_utils@$VERSION/quoted_string.ts";
20+
* import {
21+
* assert,
22+
* assertFalse,
23+
* } from "https://deno.land/std@$VERSION/testing/asserts.ts";
24+
*
25+
* assert(isQdtext("\t"));
26+
* assert(isQdtext("\xFF"));
27+
* assertFalse(isQdtext(`"`));
28+
* ```
29+
*/
30+
export function isQdtext(input: string): boolean {
31+
return reQdtext.test(input);
32+
}

quoted_string_test.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { isQdtext } from "./quoted_string.ts";
2+
import {
3+
assert,
4+
assertEquals,
5+
assertFalse,
6+
assertThrows,
7+
describe,
8+
it,
9+
} from "./_dev_deps.ts";
10+
11+
function charRange(start: string, end: string): string[] {
12+
if (end < start) throw RangeError();
13+
14+
return Array.from(new Array(end.charCodeAt(0) - start.charCodeAt(0) + 1)).map(
15+
(
16+
_,
17+
i,
18+
) => String.fromCharCode(start.charCodeAt(0) + i),
19+
);
20+
}
21+
22+
describe("charRange", () => {
23+
it("should throw error is the range is invalid", () => {
24+
const table: [string, string, string[]][] = [
25+
["A", "C", ["A", "B", "C"]],
26+
["A", "A", ["A"]],
27+
["\x21", "\x24", ["\x21", "\x22", "\x23", "\x24"]],
28+
];
29+
30+
table.forEach(([start, end, expected]) => {
31+
assertEquals(charRange(start, end), expected);
32+
});
33+
});
34+
35+
it("should throw error is the range is invalid", () => {
36+
assertThrows(() => charRange("b", "a"));
37+
});
38+
});
39+
40+
describe("describe", () => {
41+
it("should return true", () => {
42+
const table: string[] = [
43+
"\t",
44+
" ",
45+
"\x21",
46+
...charRange("\x23", "\x5B"),
47+
...charRange("\x5D", "\x7E"),
48+
...charRange("\x80", "\xFF"),
49+
];
50+
51+
table.forEach((input) => {
52+
assert(isQdtext(input));
53+
});
54+
});
55+
56+
it("should return false", () => {
57+
const table: string[] = [
58+
"",
59+
...charRange("\x00", "\x08"), // \x09 is "\t"
60+
...charRange("\x10", "\x19"), // \x20 is " "
61+
"\x22",
62+
"\xFF" + 1,
63+
"\x22\x22",
64+
];
65+
66+
table.forEach((input) => {
67+
assertFalse(isQdtext(input), input);
68+
});
69+
});
70+
});

0 commit comments

Comments
 (0)