-
Notifications
You must be signed in to change notification settings - Fork 4
/
ini.ml
65 lines (50 loc) · 1.45 KB
/
ini.ml
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
open Tyre.Infix
type section = string * (string * string) list
type ini =
{ named: section list
; anon: (string * string) list }
let take_till cset = Re.(rep (compl [set cset])) |> Tyre.regex
let strip = Tyre.conv String.trim (fun x -> x)
let section_title =
let open! Tyre in
let sec_name = "]" |> take_till |> strip in
char '[' *> sec_name <* char ']'
let entry : (string * string) Tyre.t =
let open Tyre in
let equal = blanks *> char '=' <* blanks in
let key = strip @@ take_till "[]=" in
key <&> equal *> take_till "\n"
let empty_line =
Re.( seq [rep (set " \t") ; char '\n'] |> rep )
|> Tyre.regex
let line t =
let open Tyre in
t <* blanks <* char '\n'
let entry =
empty_line *> entry <* empty_line
let section = Tyre.(terminated_list ~sep:(char '\n') entry)
let named_section =
line section_title <&> section
let ini =
Tyre.start *> section <&> Tyre.list named_section <* Tyre.stop
|> Tyre.conv
(fun (anon, named) -> { anon ; named })
(fun { anon ; named } -> (anon, named))
let sample_ini =
{ anon=[ "lang", "OCaml"
; "lib", "foo bar" ]
; named =
[ "lib",
[ "re", "1.5.0"
; "tyre", "> 1.5.0" ]
; "src",
[ "one", "two"
; "xxx", "foo bar baz" ]
; "lib_test",
[ "alcotest", "*" ]
]
}
let sample_ini_str = Tyre.eval ini sample_ini
let sample_ini' = Tyre.exec (Tyre.compile ini) sample_ini_str
let () =
assert (Result.Ok sample_ini = sample_ini')