Unity

An Elixir unit conversion calculator inspired by the Unix units utility. Uses Localize as the primary engine for unit creation, conversion, arithmetic, and localized output.

Features

Installation

Add unity to your list of dependencies in mix.exs:

def deps do
  [
    {:unity, "~> 0.1.0"}
  ]
end

Library usage

iex> {:ok, result, _env} = Unity.eval("3 meters to feet")
iex> result.value
9.84251968503937

iex> Unity.format!(Unity.eval!("60 mph to km/h"))
"96.56064 kilometers per hour"

iex> Unity.format!(Unity.eval!("100 celsius to fahrenheit"))
"212 degrees Fahrenheit"

iex> {:ok, result, _env} = Unity.eval("3.756 hours to h;min;s")
iex> Unity.format!(result)
"3 hours, 45 minutes, 21.6 seconds"

Variables

iex> {:ok, _, env} = Unity.eval("let distance = 42.195 km")
iex> {:ok, _, env} = Unity.eval("let time = 2 hours", env)
iex> {:ok, result, _} = Unity.eval("distance / time", env)
iex> result.name
"kilometer-per-hour"

Measurement system conversion

iex> Unity.format!(Unity.eval!("100 meter to us"))
"0.062137 miles"

iex> Unity.format!(Unity.eval!("100 fahrenheit to metric"))
"37.777778 degrees Celsius"

iex> Unity.format!(Unity.eval!("100 meter to imperial"))
"0.062137 miles"

# "preferred" uses the current locale's measurement system
iex> Localize.put_locale(:de)
iex> Unity.format!(Unity.eval!("100 fahrenheit to preferred"))
"37,777778 Grad Celsius"

Locale-aware output

iex> result = Unity.eval!("1234.5 meter to kilometer")
iex> Unity.format!(result, locale: :de)
"1,2345 Kilometer"
iex> Unity.format!(result, locale: :ja)
"1.2345 キロメートル"

Interactive REPL

$ mix run -e "Unity.Repl.start()"
Unity v0.1.0 — type "help" for commands, "quit" to exit

> 3 meters to feet
9.84252 feet

> 60 mph to km/h
96.56064 kilometers per hour

> 100 kg * 9.8 m/s^2
980 kilogram-meter-per-square-second

> 1 gallon to liters
3.785412 liters

> 12 ft + 3 in to ft
12.25 feet

> sqrt(9 m^2)
3 meters

> _ to cm
300 centimeters

> 1|3 cup to mL
78.862746 milliliters

> 3.756 hours to h;min;s
3 hours, 45 minutes, 21.6 seconds

> let distance = 42.195 km
42.195 kilometers

> let time = 2 hours
2 hours

> distance / time
21.0975 kilometers per hour

> locale de
Locale set to :de

> 1234.5 meter to kilometer
1,2345 Kilometer

CLI (escript)

Build and install the escript:

mix escript.build

Usage:

# Interactive mode
./unity

# Single conversion
./unity "3 meters to feet"

# Two-argument conversion (GNU units style)
./unity "3 meters" "feet"

# Verbose mode
./unity -v "1 gallon" "liters"

# Terse mode (for scripts)
./unity -t "100 celsius" "fahrenheit"

# Locale-aware output
./unity --locale de "1234.5 meter to kilometer"

# Read from stdin
echo "3 meters" | ./unity - feet

# Pipe-friendly
echo "3 meters to feet" | ./unity

# List unit categories
./unity --list

# List units in a category
./unity --list length

# List conformable units
./unity --conformable meter

Expression syntax

Syntax Example Description
Conversion 3 meters to feet, 3 m -> cm, 3 m in cm Convert between units
Addition 12 ft + 3 in Add compatible units
Subtraction 10 km - 3 km Subtract compatible units
Multiplication 100 kg * 9.8 m Multiply units or values
Division 100 m / 10 s, 5 miles per hour Divide units, per = /
Exponentiation m^2, s^-2, cm3 Powers and concatenated exponents
Juxtaposition kg m / s^2 Space = implicit *, higher precedence than /
Parentheses (3 + 4) m Grouping
Functions sqrt(9 m^2), abs(-5 m) Built-in math functions
Rationals 1|3 cup Rational numbers (GNU units style)
Variables let x = 42 km Variable binding
Previous result _, _ to cm Refer to last REPL result
System target to metric, to us, to imperial, to SI Convert to measurement system
Preferred to preferred Convert to locale's preferred system
Mixed-unit 3.756 hours to h;min;s Decompose into multiple units

Operator precedence (highest to lowest)

Precedence Operators Description
1 ^, concatenated exponent cm^3, m2
2 juxtaposition (space) kg m = kg * m
3 *, /, per Explicit multiply/divide
4 +, - Add/subtract (conformable units only)
5 to, in, -> Conversion (outermost)

Supported unit aliases

Over 150 common abbreviations are supported, including:

All CLDR unit names (meter, kilogram, second, etc.) and SI-prefixed forms (kilometer, milligram, gigahertz, etc.) are accepted directly.

License

Apache-2.0