-
Notifications
You must be signed in to change notification settings - Fork 0
/
url-parser-2.type
92 lines (84 loc) · 2.15 KB
/
url-parser-2.type
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
export type function parseURL = (text) => ^{
if (parseProtocol<text> extends [infer protocol, infer rest]) {
return {
protocol,
...parseAuthority<rest>
}
} else {
return never
}
}
type function parseProtocol = (text) => ^{
if(text extends `${infer protocol}://${infer rest}`) {
return [
protocol,
rest
]
} else {
return never
}
}
type function parseUserInfo = (text) => ^{
if(text extends `${infer username}:${infer password}`) {
return { username, password }
} else {
return { username: text }
}
}
type function parseAuthority = (text) => ^{
if(text extends `${infer authority}@${infer rest}`) {
return {
authority: parseUserInfo<authority>,
...parseHost<rest>
}
} else {
return {
authority: null,
rest: text
}
}
}
type function parseHost = (text) => ^{
if(text extends `${infer name}:${infer port}`) {
return ^{
if(parsePort<port> extends never) {
return never
} else {
return { name, port }
}
}
} else {
return { name: text }
}
}
type function parsePort = (text) => ^{
if(isNumberString<text> extends true) {
return text
} else {
return never
}
}
type function isNumberString = (text) => ^{
if(text extends "") {
return never
} else {
return _isNumberString<text>
}
}
type function _isNumberString = (text) => ^{
/* the end of recursion: each char of text is digit, no more chars to inspect */
if(text extends "") {
return true
} else if(text extends `${infer digit}${infer rest}`) {
return ^{
if(digit extends Digit) {
return _isNumberString<rest>
} else {
return false
}
}
} else {
return false
}
}
type Digit = union ["0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9"]