# xvw / mizur

Mizur is a tool to simplify the handling of units, and units coercion/mapping. (it is an evolution of Abacus)
Elixir Fetching latest commit…
Cannot retrieve the latest commit at this time.
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

# 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. (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)
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.