defmodule Mv.Membership.CustomFieldSort do @moduledoc """ Derives a term-order-comparable sort key from a custom-field value. Custom-field values are stored in an Ash `:union` attribute, so a value arrives either as an `%Ash.Union{}` or as its already-unwrapped term. This module is the single source of truth for turning such a value into a key that `Enum.sort_by/2` can order correctly per `value_type`. nil / empty handling is intentionally NOT this function's concern — the call sites split present from absent values before sorting. """ @doc """ Returns a term-order-comparable sort key for `value`, given its `value_type`. For every non-date type the natural unwrapped value is returned, so `:integer` sorts numerically and `:string` / `:email` sort lexicographically. """ def sort_key(%Ash.Union{value: value, type: type}, _expected_type), do: sort_key(value, type) def sort_key(value, :string) when is_binary(value), do: value def sort_key(value, :integer) when is_integer(value), do: value def sort_key(value, :boolean) when is_boolean(value), do: value # Gregorian day count is a chronological integer key (earlier date ⇒ smaller). def sort_key(%Date{} = date, :date), do: Date.to_gregorian_days(date) def sort_key(value, :email) when is_binary(value), do: value def sort_key(value, _type), do: to_string(value) end