-
Notifications
You must be signed in to change notification settings - Fork 0
/
conversion.ex
90 lines (70 loc) · 1.66 KB
/
conversion.ex
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
defprotocol BetterNumber.Conversion do
@moduledoc "Converts values to formats consumable by BetterNumber."
@fallback_to_any false
@doc "Converts a value to a Float."
def to_float(value)
@doc "Converts a value to a Decimal."
def to_decimal(value)
@doc "Converts a value to an Integer in an Either style."
def to_integer(value)
end
defimpl BetterNumber.Conversion, for: BitString do
@moduledoc false
def to_float(value) do
case Float.parse(value) do
{float, _} -> float
:error -> raise ArgumentError, "could not convert #{inspect(value)} to float"
end
end
def to_decimal(value) do
string = String.Chars.to_string(value)
Decimal.new(string)
end
def to_integer(value) do
case Integer.parse(value) do
{int, ""} -> {:ok, int}
_ -> {:error, value}
end
end
end
defimpl BetterNumber.Conversion, for: Float do
@moduledoc false
def to_float(value), do: value
def to_decimal(value) do
Decimal.from_float(value)
end
def to_integer(value) do
value
|> to_decimal()
|> BetterNumber.Conversion.Decimal.to_integer()
end
end
defimpl BetterNumber.Conversion, for: Integer do
@moduledoc false
def to_float(value), do: value * 1.0
def to_decimal(value) do
Decimal.new(value)
end
def to_integer(value) do
{:ok, value}
end
end
defimpl BetterNumber.Conversion, for: Decimal do
@moduledoc false
def to_float(value) do
{float, _} =
value
|> Decimal.to_string()
|> Float.parse()
float
end
def to_decimal(value) do
value
end
def to_integer(value) do
{:ok, Decimal.to_integer(value)}
rescue
_ ->
{:error, value}
end
end