Skip to content

Commit 9af9114

Browse files
committed
perf(parse): simplify regex pattern
1 parent dbed45b commit 9af9114

File tree

3 files changed

+37
-38
lines changed

3 files changed

+37
-38
lines changed

_abnf.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
1-
import {
2-
atomic,
3-
either,
4-
maybe,
5-
namedCapture,
6-
sequence,
7-
suffix,
8-
} from "npm:compose-regexp";
1+
import { either, namedCapture, sequence, suffix } from "npm:compose-regexp";
92
import { optimize } from "https://esm.sh/regexp-tree";
103

114
const tchar = /[!#$%&'*+.^_`|~\dA-Za-z-]/;
12-
const token = atomic(suffix("+", tchar));
5+
const token = suffix("+", tchar);
136
const SP = / /;
147

158
const OWS = /[ \t]*/;
169
const BWS = OWS;
1710

18-
const element = sequence(
19-
atomic(
20-
maybe(atomic(/.*?/), atomic(suffix("*", OWS, ",", OWS, maybe(/.*?/)))),
21-
),
22-
);
23-
2411
const DQUOTE = /"/;
2512
const obsText = /[\x80-\xFF]/;
2613
const HTAB = /\t/;
@@ -30,7 +17,7 @@ const quotedPair = sequence("\\", either(HTAB, SP, VCHAR, obsText));
3017

3118
const quotedString = sequence(
3219
DQUOTE,
33-
atomic(suffix("*", either(qdtext, quotedPair))),
20+
suffix("*", either(qdtext, quotedPair)),
3421
DQUOTE,
3522
);
3623

@@ -46,6 +33,5 @@ const authParam = sequence(
4633
);
4734

4835
if (import.meta.main) {
49-
console.log("element: ", element);
5036
console.log("authParam: ", optimize(authParam).toRegExp());
5137
}

deps.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ export { head } from "https://deno.land/x/[email protected]/head.ts";
66
export { isString } from "https://deno.land/x/[email protected]/is_string.ts";
77
export { isNullable } from "https://deno.land/x/[email protected]/is_nullable.ts";
88
export { mapValues } from "https://deno.land/[email protected]/collections/map_values.ts";
9-
export { isQuotedString } from "https://deno.land/x/[email protected]/quoted_string.ts";
10-
export { isToken } from "https://deno.land/x/[email protected]/token.ts";
9+
export {
10+
isQuotedString,
11+
type QuotedString,
12+
} from "https://deno.land/x/[email protected]/quoted_string.ts";
13+
export {
14+
isToken,
15+
type Token,
16+
} from "https://deno.land/x/[email protected]/token.ts";
1117
export { parseListFields } from "https://deno.land/x/[email protected]/list.ts";
1218
export { default as escapeStringRegExp } from "https://esm.sh/[email protected]?pin=v118";

parse.ts

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
isString,
88
isToken,
99
parseListFields,
10+
type QuotedString,
11+
type Token,
1012
toLowerCase,
1113
} from "./deps.ts";
1214
import { Msg } from "./constants.ts";
@@ -64,37 +66,20 @@ export function parseAuthorization(input: string): Authorization {
6466
return { authScheme, params };
6567
}
6668

67-
/** Generate from _abnf.ts. */
68-
const reAuthParam =
69-
/^(?<key>(?=([\w!#$%&'*+.^`|~-]+))\2)[\t ]*=[\t ]*(?:(?<token>(?=([\w!#$%&'*+.^`|~-]+))\4)|(?<quotedString>"(?=((?:\t| |!|[ \x23-\x5B\x5D-\x7E]|[\x80-\xFF]|\\(?:\t| |[\x21-\x7E]|[\x80-\xFF]))*))\6"))$/;
70-
7169
type AuthParamGroups =
7270
& { key: string }
7371
& ({ token: string; quotedString: never } | {
7472
token: never;
7573
quotedString: string;
7674
});
7775

78-
/** Parse string into {@link AuthParam}.
76+
/** Parse string into {@link AuthParams}.
7977
* @throws {SyntaxError} It the input is invalid [auth-param](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2-5).
8078
* @throws {Error} If the auth param key is duplicated.
8179
*/
8280
export function parseAuthParams(input: string): AuthParams {
8381
const list = parseListFields(input);
84-
85-
const entries = list.map((el) => {
86-
const result = reAuthParam.exec(el);
87-
88-
if (!result || !result.groups) throw new SyntaxError(Msg.InvalidSyntax);
89-
90-
const groups = result.groups as AuthParamGroups;
91-
const value = isString(groups.token)
92-
? groups.token
93-
: groups.quotedString.replace(/\\(.)/g, "$1");
94-
95-
return [groups.key, value] as const;
96-
});
97-
82+
const entries = list.map(parseAuthParam);
9883
const duplicates = duplicate(
9984
entries
10085
.map<string>(head)
@@ -105,3 +90,25 @@ export function parseAuthParams(input: string): AuthParams {
10590

10691
return Object.fromEntries(entries);
10792
}
93+
94+
type AuthParam = [key: string, value: Token | QuotedString];
95+
96+
/** Generate from _abnf.ts. */
97+
const reAuthParam =
98+
/^(?<key>[\w!#$%&'*+.^`|~-]+?)[\t ]*?=[\t ]*?(?:(?<token>[\w!#$%&'*+.^`|~-]+?)|(?<quotedString>"(?:\t| |!|[ \x23-\x5B\x5D-\x7E]|[\x80-\xFF]|\\(?:\t| |[\x21-\x7E]|[\x80-\xFF]))*?"))$/;
99+
100+
/** Parse string into {@link AuthParam}.
101+
* @throws {SyntaxError} It the input is invalid [auth-param](https://www.rfc-editor.org/rfc/rfc9110.html#section-11.2-5).
102+
*/
103+
function parseAuthParam(input: string): AuthParam {
104+
const result = reAuthParam.exec(input);
105+
106+
if (!result || !result.groups) throw new SyntaxError(Msg.InvalidSyntax);
107+
108+
const groups = result.groups as AuthParamGroups;
109+
const value = isString(groups.token)
110+
? groups.token as Token
111+
: groups.quotedString.replace(/\\(.)/g, "$1") as QuotedString;
112+
113+
return [groups.key as Token, value];
114+
}

0 commit comments

Comments
 (0)