defmodule MapSorter.SortSpec do
@moduledoc """
Defines sort spec types and generates square brackets access syntax strings.
"""
# :dob | [:birth, :date] | ["name", "maiden"]
@typedoc "Sort spec key"
@type key :: Map.key() | [Map.key()]
# Ascending or descending order...
@typedoc "Sort direction"
@type sort_dir :: :asc | :desc
# :dob | {:dob, Date} | {:desc, :dob} | {:desc, {:dob, Date}}
@typedoc "Sort spec"
@type t :: key | {key, module} | {sort_dir, key} | {sort_dir, {key, module}}
@doc """
Generates a square brackets access syntax string from a sort spec `key`.
## Examples
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets([:birth, :date])
"[:birth][:date]"
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets([:address, CITY, :state])
~s<[:address][CITY][:state]>
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets([:dob])
"[:dob]"
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets(:dob)
"[:dob]"
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets(DOB)
"[DOB]"
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets([1, <<1, 2, 3>>, 3.14, DOB])
~s{[1][<<1, 2, 3>>][3.14][DOB]}
iex> import MapSorter.SortSpec, only: [brackets: 1]
iex> brackets([DOB, "3.14", 3.14, 0, {1, 2}, :likes])
~s<[DOB]["3.14"][3.14][0][{1, 2}][:likes]>
"""
@spec brackets(key) :: String.t()
def brackets(key) when is_list(key) do
if List.ascii_printable?(key) do
# A printable charlist...
"[#{inspect(key)}]"
else
# A list of sort keys...
Enum.map_join(key, &brackets/1)
end
end
def brackets(key) do
"[#{inspect(key)}]"
end
end