-
-
Notifications
You must be signed in to change notification settings - Fork 99
/
t-inet.ts
52 lines (42 loc) · 1.46 KB
/
t-inet.ts
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
import { Evaluator } from '../evaluator';
import { TypeBase } from './datatype-base';
import { DataType, nil, QueryError } from '../interfaces';
import { _ISchema, _IType } from '../interfaces-private';
// https://www.postgresql.org/docs/13/datatype-net-types.html#DATATYPE-INET
export class INetType extends TypeBase<string> {
get primary(): DataType {
return DataType.inet
}
doCanCast(to: _IType) {
return to.primary === DataType.text;
}
doCast(value: Evaluator<string>, to: _IType<string>): Evaluator<any> | nil {
return value;
}
prefer(type: _IType<any>): _IType | nil {
return this;
}
doCanBuildFrom(from: _IType): boolean | nil {
return from.primary === DataType.text;
}
doBuildFrom(value: Evaluator<string>, from: _IType<string>): Evaluator<string> | nil {
return value
.setConversion(x => {
const [_, a, b, c, d, __, m] = /^(\d+)\.(\d+)\.(\d+)\.(\d+)(\/(\d+))?$/.exec(x) ?? []
if ([a, b, c, d].some(notByte) || notMask(m)) {
throw new QueryError(`invalid input syntax for type inet: ${x}`);
}
return x;
}, toInet => ({ toInet }));
}
}
function notByte(b: string) {
return !b
|| b.length > 1 && b[0] === '0'
|| parseInt(b, 10) > 255;
}
function notMask(b: string) {
return b
&& (b.length > 1 && b[0] === '0'
|| parseInt(b, 10) > 32);
}