blob: 1f71fbcc7d505a9588f14cb0fba5c30ba363396e (
plain)
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
|
(.module:
[library
[lux #*
[control
pipe
[monad (#+ do)]
["." try (#+ Try)]
["p" parser
["l" text (#+ Parser)]]]
[data
[number
["." nat]]
["." text
["%" format (#+ format)]]
[format
["." context (#+ Context)]]
[collection
["." dictionary]]]]])
(def: component
(Parser Text)
(p.rec
(function (_ component)
(do {! p.monad}
[head (l.some (l.none_of "+%&;"))]
($_ p.either
(p.after (p.either l.end
(l.this "&"))
(in head))
(do !
[_ (l.this "+")
tail component]
(in (format head " " tail)))
(do !
[_ (l.this "%")
code (|> (l.exactly 2 l.hexadecimal)
(p.codec nat.hex)
(\ ! each text.from_code))
tail component]
(in (format head code tail))))))))
(def: (form context)
(-> Context (Parser Context))
($_ p.either
(do p.monad
[_ l.end]
(in context))
(do {! p.monad}
[key (l.some (l.none_of "=&;"))
key (l.local key ..component)]
(p.either (do !
[_ (l.this "=")
value ..component]
(form (dictionary.has key value context)))
(do !
[_ ($_ p.or
(l.one_of "&;")
l.end)]
(form (dictionary.has key "" context)))))
... if invalid form data, just stop parsing...
(\ p.monad in context)))
(def: .public (parameters raw)
(-> Text (Try Context))
(l.result raw (..form context.empty)))
|