Skip to content

Commit 02221e6

Browse files
committed
Merge branch 'add-docs-about-contracts'
2 parents 28105e6 + cefc337 commit 02221e6

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

README.md

+43
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ user_schema
3737
]
3838
```
3939

40+
Norm can also be used to specify contracts for function definitions:
41+
42+
```elixir
43+
defmodule Colors do
44+
use Norm
45+
46+
def rgb(), do: spec(is_integer() and &(&1 in 0..255))
47+
48+
def hex(), do: spec(is_binary() and &String.starts_with?(&1, "#"))
49+
50+
@contract rgb_to_hex(r :: rgb(), g :: rgb(), b :: rgb()) :: hex()
51+
def rgb_to_hex(r, g, b) do
52+
# ...
53+
end
54+
end
55+
```
56+
4057
## Installation
4158

4259
Add `norm` to your list of dependencies in `mix.exs`. If you'd like to use
@@ -385,6 +402,32 @@ gen(age) |> StreamData.map(&Integer.to_string/1) |> Enum.take(5)
385402
This allows you to compose generators however you need to while keeping your
386403
generation co-located with the specification of the data.
387404

405+
## Adding contracts to functions
406+
407+
You can `conform` data wherever it makes sense to do so in your application.
408+
But one of the most common ways to use Norm is to validate a functions arguments
409+
and return value. Because this is such a common pattern, Norm provides function
410+
annotations similar to `@spec`:
411+
412+
```elixir
413+
defmodule Colors do
414+
use Norm
415+
416+
def rgb(), do: spec(is_integer() and &(&1 in 0..255))
417+
418+
def hex(), do: spec(is_binary() and &String.starts_with?(&1, "#"))
419+
420+
@contract rgb_to_hex(r :: rgb(), g :: rgb(), b :: rgb()) :: hex()
421+
def rgb_to_hex(r, g, b) do
422+
# ...
423+
end
424+
end
425+
```
426+
427+
If the arguments for `rgb_to_hex` don't conform to the specification or if
428+
`rgb_to_hex` does not return a value that conforms to `hex` then an error will
429+
be raised.
430+
388431
## Should I use this?
389432

390433
Norm is still early in its life so there may be some rough edges. But

0 commit comments

Comments
 (0)