mte/src/timestamp.ml

70 lines
2.1 KiB
OCaml
Raw Normal View History

2025-11-28 16:57:48 +01:00
type t = Ptime.t option
type span = Ptime.Span.t option
let diff a b =
match (a, b) with
| None, _ | _, None -> None
| Some a, Some b -> Some (Ptime.diff a b)
let add_span_exn t span =
match (t, span) with
| None, _ | _, None -> None
| Some t, Some span -> (
match Ptime.add_span t span with
| None -> Fmt.failwith "add_span_exn: not in the range [min;max]"
| Some v -> Some v)
let of_span_exn = function
| None -> None
| Some span -> (
match Ptime.of_span span with
| None -> Fmt.failwith "of_span_exn: not in the range [min;max]"
| Some p -> Some p)
(* -- *)
(* microseconds since the UNIX Epoch, or "never" if None *)
let jsont =
let number_or_never_jsont =
let never =
let dec s =
match s with
| "never" -> None
| _ -> Jsont.Error.msg Jsont.Meta.none "unexpected string value"
in
let enc = function None -> "never" | _ -> assert false in
Jsont.map ~dec ~enc Jsont.string
in
let number =
let dec n = Ptime.of_float_s n in
let enc = function Some n -> Ptime.to_float_s n | _ -> assert false in
Jsont.map ~dec ~enc Jsont.number
in
let enc = function None -> never | Some _ -> number in
Jsont.any ~dec_string:never ~dec_number:number ~enc ()
in
let make t = t in
Jsont.Object.map ~kind:"Timestamp" make
|> Jsont.Object.mem "t_s" number_or_never_jsont ~enc:Fun.id
|> Jsont.Object.finish
(* TODO exn *)
let ptime_to_int64 ptime = ptime |> Ptime.to_float_s |> Int64.of_float
let ptime_of_int64 i =
match Ptime.of_float_s (Int64.to_float i) with
| None -> Fmt.failwith "ptime_of_int64 error: `%Ld` is not a valid ptime" i
| Some ts -> ts
let encode_int64 = function None -> Int64.max_int | Some p -> ptime_to_int64 p
let decode_int64 i = if i = Int64.max_int then None else Some (ptime_of_int64 i)
(* UINT64_MAX represents "never". *)
let bin = Bin.map Bin.neint64 decode_int64 encode_int64
let bin_nbo = Bin.map Bin.beint64 decode_int64 encode_int64
let caqti : Ptime.t option Caqti_type.t =
let encode v = Ok (encode_int64 v) in
let decode v = Ok (decode_int64 v) in
Caqti_type.custom ~encode ~decode Caqti_type.int64