defmodule Kameleoon.Data.Validation do @moduledoc false @max_u32 4_294_967_295 def keyword!(opts, defaults) when is_list(opts), do: Keyword.validate!(opts, defaults) def keyword!(value, _defaults) do raise ArgumentError, "expected options to be a keyword list, got: #{inspect(value)}" end def one_of!(value, allowed, key) do if value in allowed do value else raise ArgumentError, "expected #{inspect(key)} to be one of #{inspect(allowed)}, got: #{inspect(value)}" end end def u32!(value, _key) when is_integer(value) and value >= 0 and value <= @max_u32, do: value def u32!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be an unsigned 32-bit integer, got: #{inspect(value)}" end def non_empty_string!(value, _key) when is_binary(value) and byte_size(value) > 0, do: value def non_empty_string!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a non-empty string, got: #{inspect(value)}" end def string_or_nil!(nil, _key), do: nil def string_or_nil!(value, _key) when is_binary(value), do: value def string_or_nil!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a string or nil, got: #{inspect(value)}" end def number_or_nil!(nil, _key), do: nil def number_or_nil!(value, _key) when is_number(value), do: value def number_or_nil!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a number or nil, got: #{inspect(value)}" end def boolean!(value, _key) when is_boolean(value), do: value def boolean!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a boolean, got: #{inspect(value)}" end def string_list!(values, _key) when is_list(values) do if Enum.all?(values, &is_binary/1) do values else raise ArgumentError, "expected :values to contain only strings" end end def string_list!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a list, got: #{inspect(value)}" end def integer_list!(values, _key) when is_list(values) do if Enum.all?(values, &is_integer/1) do values else raise ArgumentError, "expected :referrers to contain only integers" end end def integer_list!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a list, got: #{inspect(value)}" end def cookie_map!(cookies, _key) when is_map(cookies) do if Enum.all?(cookies, fn {key, value} -> is_binary(key) and is_binary(value) end) do cookies else raise ArgumentError, "expected cookies to be a map of string keys and string values" end end def cookie_map!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a map, got: #{inspect(value)}" end def custom_data_list!(values, _key) when is_list(values) do if Enum.all?(values, &custom_data?/1) do values else raise ArgumentError, "expected :metadata to contain only Kameleoon.Data.CustomData structs" end end def custom_data_list!(value, key) do raise ArgumentError, "expected #{inspect(key)} to be a list, got: #{inspect(value)}" end defp custom_data?(value) when is_map(value) do Map.get(value, :__struct__) == Kameleoon.Data.CustomData end defp custom_data?(_value), do: false end