ash/lib/ash/ci_string.ex
Zach Daniel 80a65db150 improvement: various validation lifecycle options
fix: various validation lifecycle fixes
fix: don't fetch sideloads for empty data
2021-03-04 22:48:15 -05:00

77 lines
1.8 KiB
Elixir

defmodule Ash.CiString do
@moduledoc """
Represents a case insensitive string
While some data layers are aware of case insensitive string types, in order for values
of this type to be used in other parts of Ash Framework, it has to be embedded in a module
this allows us to implement the `Comparable` protocol for it.
For the type implementation, see `Ash.Type.CiString`
"""
defstruct [:string, lowered?: false]
def sigil_i(value), do: new(value)
defimpl Jason.Encoder do
def encode(ci_string, _opts) do
Ash.CiString.value(ci_string)
end
end
defimpl String.Chars do
def to_string(ci_string) do
Ash.CiString.value(ci_string)
end
end
defimpl Inspect do
import Inspect.Algebra
def inspect(%Ash.CiString{string: string}, opts) do
concat(["#Ash.CiString<", to_doc(string, opts), ">"])
end
end
def new(value) do
%Ash.CiString{lowered?: true, string: value && String.downcase(value)}
end
def value(%Ash.CiString{string: value, lowered?: false}) do
value && String.downcase(value)
end
def value(%Ash.CiString{string: value, lowered?: true}) do
value
end
def compare(left, right) do
do_compare(to_binary(left), to_binary(right))
end
defp do_compare(left, right) when left < right, do: :lt
defp do_compare(left, right) when left == right, do: :eq
defp do_compare(_, _), do: :gt
defp to_binary(value) when is_binary(value) do
String.downcase(value)
end
defp to_binary(%__MODULE__{lowered?: false, string: value}) do
value && String.downcase(value)
end
defp to_binary(%__MODULE__{string: value}) do
value
end
end
use Comp
defcomparable left :: Ash.CiString, right :: BitString do
Ash.CiString.compare(left, right)
end
defcomparable left :: Ash.CiString, right :: Ash.CiString do
Ash.CiString.compare(left, right)
end