Skip to content

Commit

Permalink
Cldr.Unit.Conversion.convert/2 now supports units with a decimal value.
Browse files Browse the repository at this point in the history
Closes #8
  • Loading branch information
kipcole9 committed Aug 26, 2018
1 parent fbb8915 commit 6dfb815
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 14 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Changelog for Cldr_Units v1.2.2

This is the changelog for Cldr v1.2.2 released on August 26th, 2018. For older changelogs please consult the release tag on [GitHub](https://github.com/kipcole9/cldr_units/tags)

## Bug Fixes

* `Cldr.Unit.Conversion.convert/2` now correctly accepts units with a decimal value. Fixes #8. Thanks to @lostkobrakai.

# Changelog for Cldr_Units v1.2.1

This is the changelog for Cldr v1.2.1 released on May 9th, 2018. For older changelogs please consult the release tag on [GitHub](https://github.com/kipcole9/cldr_units/tags)
Expand Down
59 changes: 53 additions & 6 deletions lib/cldr/conversion.ex
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,39 @@ defmodule Cldr.Unit.Conversion do
# {to_celsius, from_celsius}
temperature: %{
celsius: 1,
fahrenheit: {&((&1 - 32) / 1.8), &(&1 * 1.8 + 32)},
fahrenheit: {
fn
x when is_number(x) ->
(x - 32) / 1.8
%Decimal{} = x ->
Decimal.sub(x, Decimal.new(32))
|> Decimal.div(Decimal.new("1.8"))
end,

fn
x when is_number(x) ->
(x * 1.8) + 32
%Decimal{} = x ->
Decimal.mult(x, Decimal.new("1.8"))
|> Decimal.add(Decimal.new(32))
end
},
generic: :not_convertible,
kelvin: {&(&1 - 273.15), &(&1 + 273.15)}
kelvin: {
fn
x when is_number(x) ->
(x - 273.15)
%Decimal{} = x ->
Decimal.sub(x, Decimal.new("273.15"))
end,

fn
x when is_number(x) ->
(x + 273.15)
%Decimal{} = x ->
Decimal.add(x, Decimal.new("273.15"))
end
},
},
volume: %{
acre_foot: 8.1071e-7,
Expand Down Expand Up @@ -231,18 +261,35 @@ defmodule Cldr.Unit.Conversion do
end
end

defp convert(value, from, to) when is_number(from) and is_number(to) do
defp convert(value, from, to) when is_number(value) and is_number(from) and is_number(to) do
{:ok, value / from * to}
end

defp convert(value, {to_base_fun, _}, to) when is_number(to) do
{:ok, to_base_fun.(value) * to}
defp convert(%Decimal{} = value, from, to) when is_number(from) and is_number(to) do
converted =
value
|> Decimal.div(Decimal.new(from))
|> Decimal.mult(Decimal.new(to))

{:ok, converted}
end

defp convert(value, {to_base_fun, _}, to) when is_number(value) and is_number(to) do
{:ok,to_base_fun.(value) * to}
end

defp convert(value, from, {_to_fun, from_base_fun}) when is_number(from) do
defp convert(%Decimal{} = value, {to_base_fun, _}, to) when is_number(to) do
{:ok,Decimal.mult(to_base_fun.(value), Decimal.new(to))}
end

defp convert(value, from, {_to_fun, from_base_fun}) when is_number(value) and is_number(from) do
{:ok, from_base_fun.(value / from)}
end

defp convert(%Decimal{} = value, from, {_to_fun, from_base_fun}) when is_number(from) do
{:ok, Decimal.div(from_base_fun.(value), Decimal.new(from))}
end

defp convert(value, {to_base_fun, _}, {_, from_base_fun}) do
{:ok, from_base_fun.(to_base_fun.(value))}
end
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule CldrUnits.Mixfile do
use Mix.Project

@version "1.2.1"
@version "1.2.2"

def project do
[
Expand Down
18 changes: 11 additions & 7 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
%{
"abnf2": {:hex, :abnf2, "0.1.2", "6f8792b8ac3288dba5fc889c2bceae9fe78f74e1a7b36bea9726ffaa9d7bef95", [:mix], []},
"abnf2": {:hex, :abnf2, "0.1.4", "9a424cfe94556c0e3e58b02326c39383b170dde4777913fcbdbdfcd2f1b0a97f", [:mix], [], "hexpm"},
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.2.4", "99b637c62a4d65a20a9fb674b8cffb8baa771c04605a80c911c4418c69b75439", [:mix], []},
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
"ex_abnf": {:hex, :ex_abnf, "0.3.0", "07847d0d6cb75b779948520d02cba80eb855e18acb1aa8d43b1e370ef31afbcb", [:mix], []},
"ex_cldr": {:hex, :ex_cldr, "1.5.0", "56f8301140c29fdf7f627abb2ed458479d776a56368f745903fe47f2126e2701", [:mix], [{:abnf2, "~> 0.1", [hex: :abnf2, repo: "hexpm", optional: false]}, {:decimal, "~> 1.4", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 2.1 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "1.4.0", "5abe287bd326d1dacd67a2ffbd0f4757ef5521beffb80ad5e41b899a5e3cfa30", [:mix], [{:decimal, "~> 1.4", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 1.5.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.1 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.18.2", "993e0a95e9fbb790ac54ea58e700b45b299bd48bc44b4ae0404f28161f37a83e", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
"ex_cldr": {:hex, :ex_cldr, "1.6.4", "28b0aebdc38bb04414fce24679365a9355d1fce3ca731c7273d34927c6bdb8ce", [:mix], [{:abnf2, "~> 0.1", [hex: :abnf2, repo: "hexpm", optional: false]}, {:decimal, "~> 1.4", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 2.1 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "1.0.0", "471c6374cef63baec483bbca68e11ac804f66f1efa97c9885cff9be4b04d9ec4", [:mix], [{:ex_cldr, "~> 1.5", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.1 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "1.5.1", "3ed4f9bacccb01821a1532f256ab3da3f8ffc4870c3ea05630293ed4ccc27646", [:mix], [{:decimal, "~> 1.4", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 1.5", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 1.0", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.1 or ~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"flow": {:hex, :flow, "0.12.0", "32c5a5f3ff6693e004b6c17a8c64dce2f8cdaf9564912d79427176013a586ab6", [:mix], [{:gen_stage, "~> 0.12.0", [hex: :gen_stage, optional: false]}]},
"gen_stage": {:hex, :gen_stage, "0.12.2", "e0e347cbb1ceb5f4e68a526aec4d64b54ad721f0a8b30aa9d28e0ad749419cbb", [:mix], []},
"jason": {:hex, :jason, "1.0.0", "0f7cfa9bdb23fed721ec05419bcee2b2c21a77e926bce0deda029b5adc716fe2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, optional: true]}]},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
"jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"makeup": {:hex, :makeup, "0.5.1", "966c5c2296da272d42f1de178c1d135e432662eca795d6dc12e5e8787514edf7", [:mix], [{:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.8.0", "1204a2f5b4f181775a0e456154830524cf2207cf4f9112215c05e0b76e4eca8b", [:mix], [{:makeup, "~> 0.5.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
}
30 changes: 30 additions & 0 deletions test/cldr_units_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,34 @@ defmodule Cldr.UnitsTest do
assert Cldr.Unit.to_string!(1, locale: "de", unit: :century) == "1 Jahrhundert"
assert Cldr.Unit.to_string!(123, locale: "de", unit: :century) == "123 Jahrhunderte"
end

test "decimal" do
unit = Cldr.Unit.new(Decimal.new("300"), :minute)

hours = Cldr.Unit.Conversion.convert(unit, :hour)

assert hours.unit == :hour
assert Decimal.equal?(5, Cldr.Unit.value(Cldr.Unit.round(hours)))
end

test "decimal functional conversion - celsius" do
celsius = Cldr.Unit.new(Decimal.new("100"), :celsius)
fahrenheit = Cldr.Unit.Conversion.convert(celsius, :fahrenheit)

assert Decimal.equal?(Cldr.Unit.value(fahrenheit), Decimal.new(212))
end

test "decimal functional conversion - kelvin" do
celsius = Cldr.Unit.new(Decimal.new("0"), :celsius)
kelvin = Cldr.Unit.Conversion.convert(celsius, :kelvin)

assert Decimal.equal?(Cldr.Unit.value(kelvin), Decimal.new("273.15"))
end

test "decimal conversion without function" do
celsius = Cldr.Unit.new(Decimal.new(100), :celsius)
celsius2 = Cldr.Unit.Conversion.convert(celsius, :celsius)

assert Decimal.equal?(Cldr.Unit.value(celsius2), Decimal.new(100))
end
end

0 comments on commit 6dfb815

Please sign in to comment.