package liquid_std

  1. Overview
  2. Docs

Source file liquid_number.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
open Base
open Liquid_syntax
open Syntax
open Helpers

let abs _ params =
  let do_abs n = (if Float.(<) n 0. then n *. -1. else n) |> ok_num in
  match params with
  | Number n :: _ -> do_abs n
  | String s :: _ -> s |> Float.of_string |> do_abs
  | other -> errc "abs accepts a number" other

let at_least = pick_at_by_op Float.(<)
let at_most = pick_at_by_op Float.(>)

let ceil _ = function
  | Number n :: _ -> Float.round_up n |> ok_num
  | String s :: _ -> s |> Float.of_string |> Float.round_up |> ok_num
  | other -> errc "ceil takes a number" other

let divided_by _ = function
  | Number _ :: Number 0. :: _ ->
    err "Cannot divide by zero!"
  | Number a :: Number b :: _ ->
    a /. b |> ok_num
  | other -> errc "divided_by accepts 2 numbers" other


let floor _ = function
  | Number n :: _ -> Float.round_down n |> ok_num
  | String s :: _ -> s |> Float.of_string |> Float.round_down |> ok_num
  | other -> errc "floor accepts a number or a string containing a number" other


let minus = apply_op Float.(-)
let modulo = apply_op Float.(-)
let plus = apply_op Float.(+)
let times = apply_op Float.( * )

let round _ = function
  | Number a :: Number fplaces :: _ -> (
    let places = Float.to_int fplaces in
    Float.round_decimal a ~decimal_digits:places |> ok_num
  )
  | Number a :: _ -> Float.round_nearest a |> ok_num
  | other -> errc "round accepts a number and an option number of decimal places" other

let weight_with_unit ctx = function
  | Number n :: String u :: _ ->
    let weight_unit = parse_weight_unit u |> weight_unit_as_string in
    let literal = Values.string_from_value ctx (Number n) ^ " " ^ weight_unit in
    literal |> ok_str
  | other -> errc "weight_with_unit accepts a number and an optional unit name" other


let money ctx = function
  | Number n :: _ ->
    let info = Settings_ctx.preferred_currency_info ctx in
    format_money_symbol info n |> ok_str
  | other -> errc "money accepts a number" other

let money_with_currency ctx = function
  | Number n :: _ ->
    let info = Settings_ctx.preferred_currency_info ctx in
    format_money_currency info n |> ok_str
  | other -> errc "money_with_currency accepts a number" other

let money_without_currency _ = function
  | Number n :: _ -> format_money_number n |> ok_str
  | other -> errc "money_without_currency accepts a number" other

let money_without_trailing_zeros ctx = function
  | Number n :: _ ->
    let info = Settings_ctx.preferred_currency_info ctx in
    format_money_symbol_no_zeros info n |> ok_str
  | other -> errc "money_without_trailing_zeros accepts a number" other


let function_from_id = function
  | "abs" -> Some abs
  | "at_least" -> Some at_least
  | "at_most" -> Some at_most
  | "ceil" -> Some ceil
  | "divided_by" -> Some divided_by
  | "floor" -> Some floor
  | "minus" -> Some minus
  | "modulo" -> Some modulo
  | "plus" -> Some plus
  | "round" -> Some round
  | "times" -> Some times
  | "weight_with_unit" -> Some weight_with_unit
  | "money" -> Some money
  | "money_with_currency" -> Some money_with_currency
  | "money_without_currency" -> Some money_without_currency
  | "money_without_trailing_zeros" -> Some money_without_trailing_zeros
  | _ -> None