ExUc - Elixir Unit Converter
Converts values between units.
Installation
From Hex, the package can be installed as:
-
Add
ex_ucto your list of dependencies inmix.exs:
```elixir
def deps do
[{:ex_uc, "~> 1.0"}]
end
```Requirements
This package requires Elixir 1.3+
Usage
The quickest way is the function convert:
iex>ExUc.convert("5 pounds", "oz")
"80.00 oz"This is just a shortcut for the 3-steps pipeline:
import ExUc
new_val = from("5 pounds") # %ExUc.Value{unit: :lb, value: 5, kind: :mass}
|> to(:oz) # %ExUc.Value{unit: :oz, value: 80, kind: :mass}
|> as_string # "80.00 oz"The same unit can be identified by several aliases:
convert("5 km", "miles") # "3.11 miles"
convert("5 kms", "mi") # "3.11 mi"
convert("5 kilometers", "mile") # "3.11 mile"
convert("5km", "mile") # "3.11 mile"Errors
Only two errors are returned when found, both as self descriptive strings:
"undefined origin": Unit for the original value can't be parsed or found in any defined kind."undetermined conversion": Conversion between the given units can't be determined.
Configuration
The only two configurable variables are:
precisionHow many decimals will have the result when is converted into stringallow_exact_resultsWhentrue, truncates decimal zeros in exact results.
Could be set as:
config :ex_uc, precision: 2
config :ex_uc, allow_exact_results: falseUnits
Included are some of the most frequent units grouped by kinds:
-
Length: (
m,km,cm,mm,ft,in,yd,mi,ft_in). -
Mass: (
g,kg,mg,lb,oz,lb_oz). -
Time: (
μs,ms,s,min,h,d). -
Temperature: (
C,F,K). -
Speed: (
km/h,mph,m/s,kn). -
Pressure: (
Pa,hPa,kPa,bar,at,atm,mmHg,psi). -
Memory: (
B,KB,MB,GB,TB,PB,EB,ZB,YB,b,Kb,Mb,Gb,Tb,Pb,Eb,Zb,Yb,KiB,MiB,GiB,TiB,PiB,EiB,ZiB,YiB).
Adding More Units
Kinds are really easy to extend. You don't need to add a conversion to every other existent unit in the kind (though, of course you can). ExUc will find the shortest path in a kind of units as a graph, using defined conversions.
Unit types (kinds) should be defined using configuration options for :ex_uc application. Each unit must have definitions for units and conversions (See some included examples at config/units in this repository).
New or overridden definitions should follow this structure:
use Mix.Config
config :ex_uc, :<KIND>_units,
<UNIT>: ["alias 1", "alias 2", "alias N"], # List with every alias intended to relate to unit identified by UNIT
config :ex_uc, :<KIND>_conversions,
<UNIT_A>_to_<UNIT_B>: 0.001, # Multiplication factor
<UNIT_C>_to_<UNIT_D>: &(&1 + 5) # Conversion formula.
<UNIT_X>_to_<UNIT_Y>: :special # Atom referencing a special method. Which have two sections:
- Aliases
-
Key as
<KIND>_unitswhere kind identifies the type of measurement, e.g: length, temperature, pressure, etc. -
Each unit to support in the
kindas a pairunit:aliaseswhere unit is the most used unit and aliases is a list of strings (or a single one), one for each supported representation of the unit.
-
Key as
- Conversions
-
Key as
<KIND_conversions>using the same kind from the alias section. -
Each conversion as a pair
key:conversion, where key is an atom with the pattern<UNIT_FROM>_to_<UNIT_TO>, and conversion could be a number, or a closure, or an atom. Numeric conversions describe multiplication factors, and can be also used as<B>_to_<A>: 1 / conversionfor a<A>_to_<B>: factorwithout explicit definition. When a factor is not enough, a closure can be used as a simple formula. For special cases use an atom to describe a function in moduleSpecial.
-
Key as
Better Unit Conversions
PRs or Issues with new units or more accurate conversions are welcome.
Documentation
Detailed documentation can be found at hex docs.
Note
This project was inspired by the awesome Ruby gem by Kevin C. Olbrich, Ph.D.