defmodule Uptight do
@moduledoc """
Facilities for tightening loosey goosey types.
"""
alias Uptight.Text, as: T
alias Uptight.Base, as: B
alias Uptight.Binary
alias Uptight.Result
import Witchcraft.Functor
@spec tighten(any) :: any
def tighten(x) when is_binary(x) do
candidate = T.new(x)
candidate =
if Result.is_err?(candidate) do
%Result.Ok{ok: Binary.new!(x)}
else
candidate
end
candidate.ok
end
def tighten([x]) do
[tighten(x)]
end
def tighten([x | rest]) do
[tighten(x) | tighten(rest)]
end
def tighten({t, x}) do
{t, tighten(x)}
end
def tighten(%{} = kv) do
map(kv, &tighten/1)
end
def tighten(x), do: x
@spec into_text_or_urlsafe(binary) :: T.t() | B.Urlsafe.t()
def into_text_or_urlsafe(x) do
case tighten(x) do
x = %Binary{} -> B.binary_to_urlsafe(x)
x = %T{} -> x
end
end
end