Packages
croma
0.4.1
0.13.0
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Elixir macro utilities to make type-based programming easier
Current section
Files
Jump to
Current section
Files
lib/croma/validation.ex
defmodule Croma.Validation do
@moduledoc """
Module for code generation of argument validation (see `Croma.Defun.defun/2`).
This module is intended for internal use.
"""
def make(type_expr, v, caller) do
case type_expr do
l when is_list(l) -> validation_expr(v, [], Croma.List)
{_, _} -> validation_expr(v, [], Croma.Tuple)
{:t, meta, _} -> validation_expr(v, meta)
{{:., meta, [mod_alias, :t]}, _, _} -> validation_expr(v, meta, replace_elixir_type_module(mod_alias, caller))
{first, meta, _} -> make_from_tuple3(type_expr, v, first, meta)
_ -> error(type_expr)
end
end
defp make_from_tuple3(type_expr, v, first, meta) do
mod =
case first do
:integer -> Croma.Integer
:pos_integer -> Croma.PosInteger
:neg_integer -> Croma.NeInteger
:non_neg_integer -> Croma.NonNegInteger
:byte -> Croma.Byte
:char -> Croma.Char
:float -> Croma.Float
:number -> Croma.Number
:binary -> Croma.Binary
:bitstring -> Croma.BitString
:module -> Croma.Atom
:atom -> Croma.Atom
:node -> Croma.Atom
:fun -> Croma.Function
:pid -> Croma.Pid
:port -> Croma.Port
:reference -> Croma.Reference
:char_list -> Croma.List
:list -> Croma.List
:map -> Croma.Map
:tuple -> Croma.Tuple
:%{} -> Croma.Map
:{} -> Croma.Tuple
:<<>> -> Croma.BitString
_ -> error(type_expr)
end
validation_expr(v, meta, mod)
end
defp validation_expr(v, meta) do
{name, _, _} = v
rhs = quote bind_quoted: [name: name, v: v] do
case validate(v) do
{:ok , value } -> value
{:error, reason} -> raise "validation error for #{Atom.to_string(name)}: #{inspect reason}"
end
end
{:=, meta, [v, rhs]}
end
defp validation_expr(v, meta, mod) do
{name, _, _} = v
rhs = quote bind_quoted: [name: name, v: v, mod: mod] do
case mod.validate(v) do
{:ok , value } -> value
{:error, reason} -> raise "validation error for #{Atom.to_string(name)}: #{inspect reason}"
end
end
{:=, meta, [v, rhs]}
end
defp replace_elixir_type_module(mod_alias, caller) do
mod = Macro.expand(mod_alias, caller)
case mod do
String -> Croma.String
_ -> mod
end
end
defp error(type_expr) do
raise "cannot generate validation code for the given type: #{Macro.to_string(type_expr)}"
end
end