Current section
Files
Jump to
Current section
Files
lib/options.ex
# Copyright (c) 2018 James Laver
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
defmodule Bricks.Options do
@moduledoc false
alias Bricks.Error.{BadOption, UnknownOptions}
import Bricks.Guards
def optional(opts, defs) do
defs
|> Enum.map(fn {k, v} -> optional(opts, k, v) end)
|> Enum.concat()
end
def optional(opts, key, prop_key) do
case Map.fetch(opts, key) do
{:ok, val} -> [{prop_key, val}]
_ -> []
end
end
def required(opts, key, test, valid) do
case Map.fetch(opts, key) do
{:ok, val} ->
if test.(val) do
{:ok, val}
else
{:error, BadOption.new(key, val, valid)}
end
_ ->
{:error, BadOption.new(key, nil, valid)}
end
end
def default(opts, key, default, test, permitted) do
val = Map.get(opts, key, default)
if test.(val) do
{:ok, val}
else
{:error, BadOption.new(key, val, permitted)}
end
end
def default_timeout(opts, key, default) do
default(opts, key, default, &timeout?/1, [:infinity, :non_neg_int])
end
def check_extra_keys(opts, keys) do
(Map.keys(opts) -- keys)
|> case do
[] -> :ok
keys -> {:error, UnknownOptions.new(keys)}
end
end
def table_option(opts, key, prop_key, test, valid, acc \\ []) do
case Map.fetch(opts, key) do
{:ok, val} ->
case test.(val) do
true -> {:cont, [{prop_key, val} | acc]}
_ -> {:halt, {:error, BadOption.new(key, val, valid)}}
end
_ ->
{:cont, acc}
end
end
def table_options(opts, table, extra \\ []) do
Enum.reduce_while(table, extra, fn {k, {k2, test, valid}}, acc ->
table_option(opts, k, k2, test, valid, acc)
end)
|> case do
{:error, reason} -> {:error, reason}
other -> {:ok, other}
end
end
end