Skip to content
Mizur is a tool to simplify the handling of units, and units coercion/mapping. (it is an evolution of Abacus)
Elixir
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
images
lib
test
.gitignore
LICENSE
README.md
mix.exs
mix.lock

README.md

Mizur

Pronounced /'meʒə/

Mizur is a tool to simplify the management, conversion
and mapping of units. The manipulation of measurement units should (at best) be typesafe.

Mizur Logo (A special thanks to @fh-d for this awesome logo !)

Some examples

Basic example

Definition of a metric system for computing distances :

defmodule Distance do 
  use Mizur.System
  type m
  type cm = m / 100 
  type mm = m / 1000 
  type km = m * 1000
end

Using this module provides the following functions:

  • Distance.m/0 : to reference the type Distance.m
  • Distance.cm/0 : to reference the type Distance.cm
  • Distance.mm/0 : to reference the type Distance.mm
  • Distance.km/0 : to reference the type Distance.km

and :

  • Distance.m/1 : to create packed values in the Distance.m type
  • Distance.cm/1 : to create packed values in the Distance.cm type
  • Distance.mm/1 : to create packed values in the Distance.mm type
  • Distance.km/1 : to create packed values in the Distance.km type

and sigils : Distance.sigil_t(value, ['typename']).

Example of common Mizur usage

a = Distance.m(200)
b = Distance.cm(200)
result = Mizur.add(a, b)
assert result = Distance.m(202)

Using infix notation

You can use infix notation for operations on units of measurements using use Mizur.Infix.

As with the import directive, you can use the :except and :only parameters (exactly in the same way as using import).

The main difference with import is that use will overwrite the correct operators of the Kernel module.

Manage arithmetic operations on datetime

defmodule MyTime do 

  use Mizur.System
  type sec
  type min  = sec * 60 
  type hour = sec * 60 * 60
  type day  = sec * 60 * (60 * 24)

  def now do 
    DateTime.utc_now()
    |> DateTime.to_unix(:second)
    |> sec()
  end

  def new(year, month, day, hour, min, sec) do
    ndt = NaiveDateTime.new(year, month, day, hour, min, sec) 
    case ndt do 
      {:error, message} -> raise RuntimeError, message: "#{message}"
      {:ok, value} ->
        DateTime.from_naive!(value, "Etc/UTC")
        |> DateTime.to_unix(:second)
        |> sec()
    end
  end

  def to_datetime(value) do 
    elt = Mizur.from(value, to: sec())
    int = round(Mizur.unwrap(elt))
    DateTime.from_unix!(int) #beurk, it is unsafe
  end
  
end

use Mizur.Infix, only: [+: 2, -: 2]
import MyTime

# Create a typed_value of the current timestamp:
a = now()

# Add two days and four hour
b = a + ~t(2)day + ~t(4)hour # I use Sigils... 

# Sub ten minuts 
c = b - ~t(10)min

# Convert into DateTime 
result = to_datetime(c)

Other examples

The test module gives many usage examples : Test module

Installation

If available in Hex, the package can be installed by adding mizur to your list of dependencies in mix.exs:

def deps do
  [{:mizur, "~> 0.1.1"}]
end

Special Thanks

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/mizur/readme.html.

You can’t perform that action at this time.