-
Notifications
You must be signed in to change notification settings - Fork 7
/
ascii.libsonnet
99 lines (81 loc) · 3.02 KB
/
ascii.libsonnet
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
93
94
95
96
97
98
99
local d = import 'github.com/jsonnet-libs/docsonnet/doc-util/main.libsonnet';
{
'#': d.pkg(
name='ascii',
url='github.com/jsonnet-libs/xtd/ascii.libsonnet',
help='`ascii` implements helper functions for ascii characters',
),
local cp(c) = std.codepoint(c),
'#isLower':: d.fn(
'`isLower` reports whether ASCII character `c` is a lower case letter',
[d.arg('c', d.T.string)]
),
isLower(c): cp(c) >= 97 && cp(c) < 123,
'#isUpper':: d.fn(
'`isUpper` reports whether ASCII character `c` is a upper case letter',
[d.arg('c', d.T.string)]
),
isUpper(c): cp(c) >= 65 && cp(c) < 91,
'#isNumber':: d.fn(
'`isNumber` reports whether character `c` is a number.',
[d.arg('c', d.T.string)]
),
isNumber(c): std.isNumber(c) || (cp(c) >= 48 && cp(c) < 58),
'#isStringNumeric':: d.fn(
'`isStringNumeric` reports whether string `s` consists only of numeric characters.',
[d.arg('str', d.T.string)]
),
isStringNumeric(str): std.all(std.map(self.isNumber, std.stringChars(str))),
'#isStringJSONNumeric':: d.fn(
'`isStringJSONNumeric` reports whether string `s` is a number as defined by [JSON](https://www.json.org/json-en.html).',
[d.arg('str', d.T.string)]
),
isStringJSONNumeric(str):
// "1" "9"
local onenine(c) = (cp(c) >= 49 && cp(c) <= 57);
// "0"
local digit(c) = (cp(c) == 48 || onenine(c));
local digits(str) =
std.length(str) > 0
&& std.all(
std.foldl(
function(acc, c)
acc + [digit(c)],
std.stringChars(str),
[],
)
);
local fraction(str) = str == '' || (str[0] == '.' && digits(str[1:]));
local sign(c) = (c == '-' || c == '+');
local exponent(str) =
str == ''
|| (str[0] == 'E' && digits(str[1:]))
|| (str[0] == 'e' && digits(str[1:]))
|| (std.length(str) > 1 && str[0] == 'E' && sign(str[1]) && digits(str[2:]))
|| (std.length(str) > 1 && str[0] == 'e' && sign(str[1]) && digits(str[2:]));
local integer(str) =
(std.length(str) == 1 && digit(str[0]))
|| (std.length(str) > 0 && onenine(str[0]) && digits(str[1:]))
|| (std.length(str) > 1 && str[0] == '-' && digit(str[1]))
|| (std.length(str) > 1 && str[0] == '-' && onenine(str[1]) && digits(str[2:]));
local expectInteger =
if std.member(str, '.')
then std.split(str, '.')[0]
else if std.member(str, 'e')
then std.split(str, 'e')[0]
else if std.member(str, 'E')
then std.split(str, 'E')[0]
else str;
local expectFraction =
if std.member(str, 'e')
then std.split(str[std.length(expectInteger):], 'e')[0]
else if std.member(str, 'E')
then std.split(str[std.length(expectInteger):], 'E')[0]
else str[std.length(expectInteger):];
local expectExponent = str[std.length(expectInteger) + std.length(expectFraction):];
std.all([
integer(expectInteger),
fraction(expectFraction),
exponent(expectExponent),
]),
}