···11+type t = string
22+33+let charset = "234567abcdefghijklmnopqrstuvwxyz"
44+55+let encode (n : int64) : t =
66+ let rec encode ~tid n =
77+ match n with
88+ | 0L ->
99+ tid
1010+ | n ->
1111+ encode
1212+ ~tid:(String.make 1 charset.[Int64.to_int (Int64.rem n 32L)] ^ tid)
1313+ (Int64.unsigned_div n 32L)
1414+ in
1515+ encode ~tid:"" n
1616+1717+let decode (s : t) : int64 =
1818+ let rec decode ~(n : int64) (s : string) =
1919+ match s with
2020+ | s when String.length s > 0 ->
2121+ let c = s.[0] in
2222+ let cs = String.sub s 1 (String.length s - 1) in
2323+ decode
2424+ ~n:
2525+ (Int64.add (Int64.mul n 32L)
2626+ (Int64.of_int (String.index charset c)) )
2727+ cs
2828+ | _ ->
2929+ n
3030+ in
3131+ decode ~n:0L s
3232+3333+let now () : t =
3434+ Mtime_clock.now_ns () |> Int64.unsigned_div 1_000_000L |> encode
3535+3636+let of_string (s : string) : t =
3737+ match String.length s with
3838+ | 13
3939+ when Str.string_match
4040+ (Str.regexp
4141+ "/^[234567abcdefghij][234567abcdefghijklmnopqrstuvwxyz]{12}$/" )
4242+ s 0 ->
4343+ s
4444+ | _ ->
4545+ raise (Invalid_argument (Format.sprintf "invalid tid: %s" s))
4646+4747+let to_string (s : t) : string = s
4848+4949+let of_yojson = function
5050+ | `String s ->
5151+ Ok (of_string s)
5252+ | _ ->
5353+ Error "expected string tid"
5454+5555+let to_yojson s = `String (to_string s)
5656+5757+let compare = String.compare
5858+5959+let hash = Hashtbl.hash
6060+6161+let equal = ( = )
6262+6363+let pp fmt t = Format.fprintf fmt "%s" t