Current section
Files
Jump to
Current section
Files
src/speed_trap_options.erl
-module(speed_trap_options).
-export([validate/2]).
-type bad_options() :: {bad_options, [tuple(), ...]}.
-export_type([bad_options/0]).
-spec validate(term(), boolean()) -> ok | {error, bad_options()}.
validate(Options, AllRequired) when is_map(Options) ->
DynamicOptions =
case maps:get(dynamic_rate_limiter, Options, false) of
false ->
[];
true ->
[{max_bucket_size, true, fun validate_limit_bucket_size/2},
{scaling_time_interval, true, fun validate_scaling_time_interval/1},
{rejection_rate_threshold, true, fun validate_rejection_rate_threshold/1},
{scaling_bucket_size_adjust_count, true, fun validate_scaling_bucket_size_adjust_count/1}]
end,
Errors =
lists:foldl(fun({Key, Mandatory, ValidationFn}, Errs) ->
case validate_key(Key, Options, ValidationFn, Mandatory, AllRequired) of
ok ->
Errs;
{error, Reason} ->
[Reason | Errs]
end
end,
[],
[{bucket_size, true, fun validate_bucket_size/1},
{refill_interval, true, fun validate_refill_interval/1},
{refill_count, true, fun validate_refill_count/1},
{delete_when_full, true, fun validate_delete_when_full/1},
{override, false, fun validate_override/1}]
++ DynamicOptions),
case Errors of
[] ->
ok;
_ ->
{error, {bad_options, Errors}}
end;
validate(Options, _AllPresent) ->
{error, {bad_options, [{not_a_map, Options}]}}.
%%-----------------------------------------------------------------------------
%% Internal functions
%%-----------------------------------------------------------------------------
-spec validate_key(atom(), map(), fun((term()) -> ok | {error, tuple()}), boolean(), boolean()) ->
ok | {error, tuple()}.
validate_key(Key, Options, ValidationFn, Mandatory, Required) ->
case maps:is_key(Key, Options) of
false when Required andalso Mandatory ->
{error, {key_missing, Key}};
false when not Mandatory orelse not Required ->
ok;
true ->
case erlang:fun_info(ValidationFn, arity) of
{arity, 1} ->
ValidationFn(maps:get(Key, Options));
{arity, 2} ->
ValidationFn(maps:get(Key, Options), Options)
end
end.
-spec validate_bucket_size(term()) -> ok | {error, {bucket_size, term()}}.
validate_bucket_size(BucketSize) when is_integer(BucketSize), BucketSize >= 0 ->
ok;
validate_bucket_size(BucketSize) ->
{error, {bucket_size, BucketSize}}.
validate_limit_bucket_size(MaxBucketSize, Options) ->
MinBucketSize = maps:get(min_bucket_size, Options),
AreNumbers = is_integer(MinBucketSize) andalso is_integer(MaxBucketSize),
WithinBoundaries =
MinBucketSize < MaxBucketSize andalso MinBucketSize >= 0 andalso MaxBucketSize >= 0,
case AreNumbers andalso WithinBoundaries of
true ->
ok;
false ->
{error, {limit_bucket_size, {MinBucketSize, MaxBucketSize}}}
end.
-spec validate_refill_interval(term()) -> ok | {error, {refill_interval, term()}}.
validate_refill_interval(RefillInterval) when is_integer(RefillInterval), RefillInterval > 0 ->
ok;
validate_refill_interval(RefillInterval) ->
{error, {refill_interval, RefillInterval}}.
-spec validate_refill_count(term()) -> ok | {error, {refill_count, term()}}.
validate_refill_count(RefillCount) when is_integer(RefillCount), RefillCount > 0 ->
ok;
validate_refill_count(RefillCount) ->
{error, {refill_count, RefillCount}}.
-spec validate_delete_when_full(term()) -> ok | {error, {delete_when_full, term()}}.
validate_delete_when_full(DeleteWhenFull) when is_boolean(DeleteWhenFull) ->
ok;
validate_delete_when_full(DeleteWhenFull) ->
{error, {delete_when_full, DeleteWhenFull}}.
-spec validate_override(term()) -> ok | {error, {override, term()}}.
validate_override(none) ->
ok;
validate_override(not_enforced) ->
ok;
validate_override(blocked) ->
ok;
validate_override(Override) ->
{error, {override, Override}}.
validate_scaling_time_interval(TimeInterval) when is_integer(TimeInterval), TimeInterval > 0 ->
ok;
validate_scaling_time_interval(TimeInterval) ->
{error, {invalid_time_interval, TimeInterval}}.
validate_rejection_rate_threshold(Threshold)
when is_number(Threshold), Threshold > 0, Threshold =< 100 ->
ok;
validate_rejection_rate_threshold(Threshold) ->
{error, {invalid_threshold, Threshold}}.
validate_scaling_bucket_size_adjust_count(AdjustCount)
when is_integer(AdjustCount), AdjustCount > 0 ->
ok;
validate_scaling_bucket_size_adjust_count(AdjustCount) ->
{error, {invalid_scaling_bucket_size_adjust_count, AdjustCount}}.