diff --git a/lib/drops/type.ex b/lib/drops/type.ex index 840ee27..85c4030 100644 --- a/lib/drops/type.ex +++ b/lib/drops/type.ex @@ -246,10 +246,16 @@ defmodule Drops.Type do ) end - def new(spec, constraints) when is_list(constraints) do - new( - primitive: infer_primitive(spec), - constraints: infer_constraints({:type, {spec, constraints}}) + def new(predicates, opts) when is_list(opts) do + type = new(opts) + constraints = + case type.constraints do + {:and, constraints} -> {:and, constraints ++ infer_constraints(predicates)} + constraints when is_list(constraints) -> constraints ++ infer_constraints(predicates) + end + Elixir.Map.merge( + type, + %{constraints: constraints} ) end diff --git a/lib/drops/type/dsl.ex b/lib/drops/type/dsl.ex index 58f6a44..3e52a4f 100644 --- a/lib/drops/type/dsl.ex +++ b/lib/drops/type/dsl.ex @@ -73,9 +73,9 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec type({atom(), []}) :: type() + @spec type({atom(), list()}) :: type() @spec type(list: atom()) :: type() - @spec type(list: []) :: type() + @spec type(list: list()) :: type() @spec type([atom()]) :: [type()] @spec type(atom()) :: type() @@ -113,8 +113,8 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec type(atom(), []) :: type() - @spec type({:cast, {atom(), []}}, type()) :: type() + @spec type(atom(), list()) :: type() + @spec type({:cast, {atom(), list()}}, type()) :: type() def type([type | rest], predicates) do union([type | rest], predicates) @@ -251,7 +251,7 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec maybe(atom(), []) :: type() + @spec maybe(atom(), list()) :: type() def maybe(type, predicates \\ []) do type([nil, {type, predicates}]) @@ -289,7 +289,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec string(atom()) :: type() - @spec string([]) :: type() + @spec string(list()) :: type() def string(predicate) when is_atom(predicate) do string([predicate]) @@ -335,7 +335,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec integer(atom()) :: type() - @spec integer([]) :: type() + @spec integer(list()) :: type() def integer(predicate) when is_atom(predicate) do integer([predicate]) @@ -377,7 +377,7 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec float([]) :: type() + @spec float(list()) :: type() def float(predicates) when is_list(predicates) do type(:float, predicates) @@ -460,7 +460,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec map(atom()) :: type() - @spec map([]) :: type() + @spec map(list()) :: type() def map(predicate) when is_atom(predicate) do map([predicate]) diff --git a/lib/drops/types/union.ex b/lib/drops/types/union.ex index 2c49eaf..98dbc52 100644 --- a/lib/drops/types/union.ex +++ b/lib/drops/types/union.ex @@ -101,9 +101,27 @@ defmodule Drops.Types.Union do }) end + defp constrain(%Drops.Types.Cast{input_type: input_type} = type, predicates) do + Map.merge(type, %{ + input_type: constrain(input_type, predicates) + }) + end + + defp constrain(%Drops.Types.Union{left: left, right: right} = type, predicates) do + Map.merge(type, %{ + left: constrain(left, predicates), + right: constrain(right, predicates) + }) + end + defp constrain(type, predicates) do + constraints = + case type.constraints do + {:and, constraints} -> {:and, constraints ++ infer_constraints(predicates)} + constraints when is_list(constraints) -> constraints ++ infer_constraints(predicates) + end Map.merge(type, %{ - constraints: type.constraints ++ infer_constraints(predicates) + constraints: constraints }) end end