Current section
Files
Jump to
Current section
Files
src/ffi_apollo.erl
-module(ffi_apollo).
-export([validate/2, typed/2]).
validate(X, Y) ->
X(Y).
do_check(Value, Checks) ->
lists:filtermap(
fun(Check) ->
case Check(Value) of
{ok, nil} -> false;
{error, Msg} -> {true, Msg}
end
end,
Checks
).
-spec valid_type(Type :: binary(), Value :: apollo_t:value()) -> boolean().
valid_type(Type, Value) ->
case Type of
<<"Bool">> -> is_boolean(Value);
<<"Float">> -> is_float(Value);
<<"Int">> -> is_integer(Value);
<<"String">> -> is_binary(Value);
_ -> false
end.
do_find_check(List) ->
fun({K, V}) ->
case lists:keyfind(K, 1, List) of
false ->
{true,
unicode:characters_to_binary([
<<"Invalid property name '">>, K, <<"'">>
])};
{_, {value, Type, Checks}} ->
case valid_type(Type, V) of
false ->
{true,
unicode:characters_to_binary(
[<<"Type of value `">>, "_", <<"` is not `">>, Type, <<"`">>]
)};
true ->
N = do_check(V, Checks),
case length(N) of
0 ->
false;
_ ->
[First | _] = N,
{true, First}
end
end
end
end.
typed(Constructor, List) ->
fun(Args) ->
Errored =
(lists:filtermap(
do_find_check(List),
tuple_to_list(Args)
)),
case length(Errored) of
0 ->
{ok,
apply(
Constructor,
lists:map(
fun({_, V}) -> V end, tuple_to_list(Args)
)
)};
_ ->
[First | _] = Errored,
{error, First}
end
end.