add amount.mli
This commit is contained in:
parent
cc46980a67
commit
d924b5994c
5 changed files with 48 additions and 17 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
(* TODO
|
(* TODO
|
||||||
have safe amount arithmetic
|
have safe amount arithmetic
|
||||||
make type private
|
make type private
|
||||||
use config currency option *)
|
redefine an Amount module with currency enforced to be Config.currency? *)
|
||||||
(* Amounts of currency, serialized as `<Currency>:<IntegerPart>.<FractionalPart>`
|
(* Amounts of currency, serialized as `<Currency>:<IntegerPart>.<FractionalPart>`
|
||||||
Fixed-precision numbers with 8 decimal places.
|
Fixed-precision numbers with 8 decimal places.
|
||||||
- <Currency> must be at most 11 characters long
|
- <Currency> must be at most 11 characters long
|
||||||
|
|
@ -11,9 +11,13 @@
|
||||||
|
|
||||||
Prefixed with '+' or '-' in certain contexts.
|
Prefixed with '+' or '-' in certain contexts.
|
||||||
When no sign is present, the amount is assumed to be positive. *)
|
When no sign is present, the amount is assumed to be positive. *)
|
||||||
|
type sign =
|
||||||
|
| Sign_plus
|
||||||
|
| Sign_minus
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
sign: [ `Plus | `Minus ] option;
|
sign: sign option;
|
||||||
currency: [ `Eur ];
|
currency: string;
|
||||||
value: Int64.t;
|
value: Int64.t;
|
||||||
fraction: Int32.t;
|
fraction: Int32.t;
|
||||||
}
|
}
|
||||||
|
|
@ -37,11 +41,12 @@ let make ~sign ~currency ~value ~fraction =
|
||||||
|
|
||||||
let pp =
|
let pp =
|
||||||
let open Fmt in
|
let open Fmt in
|
||||||
let pp_sign ppf = function `Plus -> char ppf '+' | `Minus -> char ppf '-' in
|
let pp_sign ppf = function
|
||||||
let pp_currency ppf = function `Eur -> string ppf "EUR" in
|
| Sign_plus -> char ppf '+'
|
||||||
|
| Sign_minus -> char ppf '-'
|
||||||
|
in
|
||||||
fun ppf { sign; currency; value; fraction } ->
|
fun ppf { sign; currency; value; fraction } ->
|
||||||
pf ppf "%a%a:%Ld.%02ld" (Fmt.option pp_sign) sign pp_currency currency value
|
pf ppf "%a%s:%Ld.%02ld" (Fmt.option pp_sign) sign currency value fraction
|
||||||
fraction
|
|
||||||
|
|
||||||
let to_string = Fmt.str "%a" pp
|
let to_string = Fmt.str "%a" pp
|
||||||
|
|
||||||
|
|
@ -50,11 +55,16 @@ let of_string =
|
||||||
let parse_sign =
|
let parse_sign =
|
||||||
choice
|
choice
|
||||||
[
|
[
|
||||||
char '+' *> return (Some `Plus); char '-' *> return (Some `Minus);
|
char '+' *> return (Some Sign_plus);
|
||||||
return None;
|
char '-' *> return (Some Sign_minus); return None;
|
||||||
]
|
]
|
||||||
in
|
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 =
|
let parse_int64 =
|
||||||
take_while1 (function '0' .. '9' -> true | _ -> false)
|
take_while1 (function '0' .. '9' -> true | _ -> false)
|
||||||
>>| Int64.of_string_opt
|
>>| Int64.of_string_opt
|
||||||
|
|
|
||||||
21
src/amount.mli
Normal file
21
src/amount.mli
Normal file
|
|
@ -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
|
||||||
|
|
@ -206,3 +206,6 @@ module Exchange_secmod_eddsa = struct
|
||||||
let lookahead_sign = get "lookahead_sign" |> duration
|
let lookahead_sign = get "lookahead_sign" |> duration
|
||||||
let overlap_duration = get "overlap_duration" |> duration
|
let overlap_duration = get "overlap_duration" |> duration
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(* -- *)
|
||||||
|
include Exchange
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ let pg_amount : Amount.t Caqti_type.t =
|
||||||
Caqti_type.custom
|
Caqti_type.custom
|
||||||
~encode:(fun amount -> Ok (amount.value, amount.fraction))
|
~encode:(fun amount -> Ok (amount.value, amount.fraction))
|
||||||
~decode:(fun (value, 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)
|
Caqti_type.(t2 int64 int32)
|
||||||
|
|
||||||
(* WIP: minimum db functions for basic /management *)
|
(* WIP: minimum db functions for basic /management *)
|
||||||
|
|
|
||||||
|
|
@ -30,12 +30,9 @@ let () =
|
||||||
let () =
|
let () =
|
||||||
let open Types.Amount in
|
let open Types.Amount in
|
||||||
let v =
|
let v =
|
||||||
{
|
Amount.make ~sign:(Some Amount.Sign_plus) ~currency:"EUR"
|
||||||
sign= Some `Plus;
|
~value:(Int64.of_int 25) ~fraction:(Int32.of_int 678)
|
||||||
currency= `Eur;
|
|> Result.get_ok
|
||||||
value= Int64.of_int 25;
|
|
||||||
fraction= Int32.of_int 678;
|
|
||||||
}
|
|
||||||
in
|
in
|
||||||
let s = to_string v in
|
let s = to_string v in
|
||||||
let v' = of_string s |> Result.get_ok in
|
let v' = of_string s |> Result.get_ok in
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue