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
100
101
102
103
104
105
106
include Stdlib.String
let to_ascii : string -> string = Ubase.from_utf8
let is_uppercase_ascii = function 'A' .. 'Z' -> true | _ -> false
let begins_with_uppercase (s : string) : bool =
"" <> s && is_uppercase_ascii (get (to_ascii s) 0)
let to_snake_case (s : string) : string =
let out = Buffer.create (2 * length s) in
s
|> to_ascii
|> iteri (fun i c ->
if is_uppercase_ascii c && 0 <> i then Buffer.add_char out '_';
Buffer.add_char out (Char.lowercase_ascii c));
Buffer.contents out
let to_camel_case (s : string) : string =
let last_was_underscore = ref true in
let out = Buffer.create (length s) in
s
|> to_ascii
|> iter (function
| '_' -> last_was_underscore := true
| c ->
Buffer.add_char out
(if !last_was_underscore then Char.uppercase_ascii c else c);
last_was_underscore := false);
Buffer.contents out
let remove_prefix ~prefix s =
if starts_with ~prefix s then
let plen = length prefix in
sub s plen (length s - plen)
else s
let width s =
let len = length s in
let rec aux ncols i =
if i >= len then ncols
else if get s i = '\t' then aux (ncols + 8) (i + 1)
else aux (ncols + 1) (i + Uchar.utf_decode_length (get_utf_8_uchar s i))
in
aux 0 0
let format ppf s = Format.pp_print_as ppf (width s) s
module Arg = struct
include Stdlib.String
let format = format
let compare s1 s2 =
let len1 = length s1 in
let len2 = length s2 in
let int c = int_of_char c - int_of_char '0' in
let rec readnum acc s i =
if i >= length s then acc, i
else
match get s i with
| '0' .. '9' as c -> readnum ((acc * 10) + int c) s (i + 1)
| _ -> acc, i
in
let rec aux i1 i2 =
if i1 >= len1 then if i2 >= len2 then 0 else -1
else if i2 >= len2 then 1
else
match get s1 i1, get s2 i2 with
| ('0' .. '9' as c1), ('0' .. '9' as c2) -> (
let x1, i1' = readnum (int c1) s1 (i1 + 1) in
let x2, i2' = readnum (int c2) s2 (i2 + 1) in
match Int.compare x1 x2 with
| 0 -> (
match Int.compare (i1' - i1) (i2' - i2) with
| 0 -> aux i1' i2'
| n -> n)
| n -> n)
| c1, c2 -> (
match Char.compare c1 c2 with 0 -> aux (i1 + 1) (i2 + 1) | n -> n)
in
aux 0 0
end
let compare = Arg.compare
module Set = Set.Make (Arg)
module Map = Map.Make (Arg)