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
type t = Int of int64 | Float of float
let int64 v = Int v
let float v = Float v
let pp ppf = function
| Int v -> Format.fprintf ppf "%Ld" v
| Float v -> Format.fprintf ppf "%f" v
let to_float = function Int v -> Int64.to_float v | Float v -> v
let to_int = function Int v -> Int64.to_int v | Float v -> Float.to_int v
let to_int64 = function Int v -> v | Float v -> Int64.of_float v
let to_int32 = function
| Int v -> Int64.to_int32 v
| Float v -> Int32.of_float v
let to_short = function
| Int v -> Int64.to_int v land 0xffff
| Float v -> Float.to_int v land 0xffff
let to_byte = function
| Int v -> Char.chr (Int64.to_int v land 0xff)
| Float v -> Char.chr (Float.to_int v land 0xff)
let to_ptime = function
| Int v -> Ptime.Span.of_int_s (Int64.to_int v)
| Float v -> (
match Ptime.Span.of_float_s v with
| Some v -> v
| None -> Fmt.invalid_arg "Invalid POSIX time value: %f" v)
let parse s =
let open Sub in
let v = to_string s in
let lexbuf = Lexing.from_string v in
if is_empty s then Error `Empty
else
match Lexer.int_or_float lexbuf with
| Ok (`Int literal) -> (
match literal.[String.length literal - 1] with
| '_' -> Error (`Invalid_number v)
| _ ->
let first = Lexing.lexeme_end lexbuf in
Ok (Int (Int64.of_string literal), with_range ~first s))
| Ok (`Float literal) ->
let first = Lexing.lexeme_end lexbuf in
Ok (Float (Float.of_string literal), with_range ~first s)
| Error `Malformed -> Error (`Invalid_number v)
| exception _ -> Error (`Invalid_number v)