Raw File
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2021 Metastate AG <hello@metastate.dev>                     *)
(*                                                                           *)
(* Permission is hereby granted, free of charge, to any person obtaining a   *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense,  *)
(* and/or sell copies of the Software, and to permit persons to whom the     *)
(* Software is furnished to do so, subject to the following conditions:      *)
(*                                                                           *)
(* The above copyright notice and this permission notice shall be included   *)
(* in all copies or substantial portions of the Software.                    *)
(*                                                                           *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL   *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING   *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER       *)
(* DEALINGS IN THE SOFTWARE.                                                 *)
(*                                                                           *)
(*****************************************************************************)

type t = int64

let of_int amount = Int64.(mul 1_000_000L (of_int amount))

let of_mutez_int = Int64.of_int

let of_mutez_int64 t = t

let zero = 0L

let one = of_int 1

let mutez_int64 t = t

let to_string amount =
  let mult_int = 1_000_000L in
  let rec left amount =
    let d, r = (Int64.(div amount 1000L), Int64.(rem amount 1000L)) in
    if d > 0L then Format.asprintf "%s%03Ld" (left d) r
    else Format.asprintf "%Ld" r
  in
  let right amount =
    let triplet v =
      if v mod 10 > 0 then Format.asprintf "%03d" v
      else if v mod 100 > 0 then Format.asprintf "%02d" (v / 10)
      else Format.asprintf "%d" (v / 100)
    in
    let hi, lo = (amount / 1000, amount mod 1000) in
    if lo = 0 then Format.asprintf "%s" (triplet hi)
    else Format.asprintf "%03d%s" hi (triplet lo)
  in
  let ints, decs =
    (Int64.(div amount mult_int), Int64.(to_int (rem amount mult_int)))
  in
  if decs > 0 then Format.asprintf "%s.%s" (left ints) (right decs)
  else left ints

let to_float amount = Float.mul (Int64.to_float amount) 0.000_001

let to_mutez amount = Int64.to_int amount

let ( + ) = Int64.add

let ( - ) = Int64.sub

let ( /! ) = Int64.div

let parse_floating tez_string =
  let re = rex "(\\d+)\\.?(\\d*)" in
  let fail () = Test.fail "Invalid tez value: '%s'." tez_string in
  let parse_int s =
    match int_of_string_opt s with None -> fail () | Some i -> i
  in
  let integral, decimal =
    match tez_string =~** re with None -> fail () | Some (i, d) -> (i, d)
  in
  let integral = parse_int integral in
  let decimal =
    match String.length decimal with
    | 0 -> 0
    | 1 -> 100_000 * parse_int decimal
    | 2 -> 10_000 * parse_int decimal
    | 3 -> 1_000 * parse_int decimal
    | 4 -> 100 * parse_int decimal
    | 5 -> 10 * parse_int decimal
    | 6 -> parse_int decimal
    | _ -> fail ()
  in
  of_int integral + of_mutez_int decimal

let typ =
  Check.comparable
    (fun fmt t -> Format.fprintf fmt "%s" (to_string t))
    (fun a b -> Int.compare (to_mutez a) (to_mutez b))
back to top