diff --git a/src/amount.ml b/src/amount.ml index 9640642c..563fc982 100644 --- a/src/amount.ml +++ b/src/amount.ml @@ -1,7 +1,7 @@ (* TODO have safe amount arithmetic make type private - use config currency option *) + redefine an Amount module with currency enforced to be Config.currency? *) (* Amounts of currency, serialized as `:.` Fixed-precision numbers with 8 decimal places. - must be at most 11 characters long @@ -11,9 +11,13 @@ Prefixed with '+' or '-' in certain contexts. When no sign is present, the amount is assumed to be positive. *) +type sign = + | Sign_plus + | Sign_minus + type t = { - sign: [ `Plus | `Minus ] option; - currency: [ `Eur ]; + sign: sign option; + currency: string; value: Int64.t; fraction: Int32.t; } @@ -37,11 +41,12 @@ let make ~sign ~currency ~value ~fraction = let pp = let open Fmt in - let pp_sign ppf = function `Plus -> char ppf '+' | `Minus -> char ppf '-' in - let pp_currency ppf = function `Eur -> string ppf "EUR" in + let pp_sign ppf = function + | Sign_plus -> char ppf '+' + | Sign_minus -> char ppf '-' + in fun ppf { sign; currency; value; fraction } -> - pf ppf "%a%a:%Ld.%02ld" (Fmt.option pp_sign) sign pp_currency currency value - fraction + pf ppf "%a%s:%Ld.%02ld" (Fmt.option pp_sign) sign currency value fraction let to_string = Fmt.str "%a" pp @@ -50,11 +55,16 @@ let of_string = let parse_sign = choice [ - char '+' *> return (Some `Plus); char '-' *> return (Some `Minus); - return None; + char '+' *> return (Some Sign_plus); + char '-' *> return (Some Sign_minus); return None; ] in - let parse_currency = string "EUR" *> return `Eur in + let parse_currency = + (* TODO currency string constraint/format *) + take_while1 (function + | 'a' .. 'z' | 'A' .. 'Z' -> true + | _ -> false) + in let parse_int64 = take_while1 (function '0' .. '9' -> true | _ -> false) >>| Int64.of_string_opt diff --git a/src/amount.mli b/src/amount.mli new file mode 100644 index 00000000..180d74dd --- /dev/null +++ b/src/amount.mli @@ -0,0 +1,21 @@ +type sign = + | Sign_plus + | Sign_minus + +type t = private { + sign: sign option; + currency: string; + value: Int64.t; + fraction: Int32.t; +} + +val make : + sign:sign option -> + currency:string -> + value:Int64.t -> + fraction:Int32.t -> + (t, string) result + +val pp : Format.formatter -> t -> unit +val to_string : t -> string +val of_string : string -> (t, string) result diff --git a/src/config.ml b/src/config.ml index 992961d6..c91ccfdb 100644 --- a/src/config.ml +++ b/src/config.ml @@ -206,3 +206,6 @@ module Exchange_secmod_eddsa = struct let lookahead_sign = get "lookahead_sign" |> duration let overlap_duration = get "overlap_duration" |> duration end + +(* -- *) +include Exchange diff --git a/src/pg.ml b/src/pg.ml index 0247996b..631d5432 100644 --- a/src/pg.ml +++ b/src/pg.ml @@ -17,7 +17,7 @@ let pg_amount : Amount.t Caqti_type.t = Caqti_type.custom ~encode:(fun amount -> Ok (amount.value, amount.fraction)) ~decode:(fun (value, fraction) -> - Ok { sign= None; currency= `Eur; value; fraction }) + Amount.make ~sign:None ~currency:Config.currency ~value ~fraction) Caqti_type.(t2 int64 int32) (* WIP: minimum db functions for basic /management *) diff --git a/test/test.ml b/test/test.ml index 45ea955a..ed024f22 100644 --- a/test/test.ml +++ b/test/test.ml @@ -30,12 +30,9 @@ let () = let () = let open Types.Amount in let v = - { - sign= Some `Plus; - currency= `Eur; - value= Int64.of_int 25; - fraction= Int32.of_int 678; - } + Amount.make ~sign:(Some Amount.Sign_plus) ~currency:"EUR" + ~value:(Int64.of_int 25) ~fraction:(Int32.of_int 678) + |> Result.get_ok in let s = to_string v in let v' = of_string s |> Result.get_ok in