@@ -37,6 +37,23 @@ user_schema
37
37
]
38
38
```
39
39
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
+
40
57
## Installation
41
58
42
59
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)
385
402
This allows you to compose generators however you need to while keeping your
386
403
generation co-located with the specification of the data.
387
404
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
+
388
431
## Should I use this?
389
432
390
433
Norm is still early in its life so there may be some rough edges. But
0 commit comments