# `Ash.Sort`
[🔗](https://github.com/ash-project/ash/blob/v3.23.1/lib/ash/sort/sort.ex#L5)

Utilities and types for sorting.

# `sort_item`

```elixir
@type sort_item() ::
  String.t()
  | atom()
  | {atom(), sort_order()}
  | %Ash.Query.Calculation{
      async?: term(),
      calc_name: term(),
      constraints: term(),
      context: term(),
      filterable?: term(),
      load: term(),
      module: term(),
      multitenancy: term(),
      name: term(),
      opts: term(),
      required_loads: term(),
      select: term(),
      sensitive?: term(),
      sortable?: term(),
      type: term()
    }
  | {%Ash.Query.Calculation{
       async?: term(),
       calc_name: term(),
       constraints: term(),
       context: term(),
       filterable?: term(),
       load: term(),
       module: term(),
       multitenancy: term(),
       name: term(),
       opts: term(),
       required_loads: term(),
       select: term(),
       sensitive?: term(),
       sortable?: term(),
       type: term()
     }, sort_order()}
  | {atom(), {Keyword.t() | map(), sort_order()}}
```

# `sort_order`

```elixir
@type sort_order() ::
  :asc
  | :desc
  | :asc_nils_first
  | :asc_nils_last
  | :desc_nils_first
  | :desc_nils_last
```

# `t`

```elixir
@type t() :: [sort_item()] | sort_item()
```

# `expr_sort`
*macro* 

```elixir
@spec expr_sort(Ash.Expr.t(), Ash.Type.t() | nil) :: Ash.Expr.t()
```

Builds an expression to be used in a sort statement. Prefer to use `Ash.Expr.calc/2` instead.

For example:

```elixir
Ash.Query.sort(query, Ash.Sort.expr_sort(author.full_name, :string))

Ash.Query.sort(query, [{Ash.Sort.expr_sort(author.full_name, :string), :desc_nils_first}])
```

# `parse_input`

```elixir
@spec parse_input(
  Ash.Resource.t(),
  String.t()
  | [atom() | String.t() | {atom(), sort_order()} | [String.t()]]
  | nil,
  nil | (String.t() -&gt; nil | atom() | {atom(), map()})
) :: {:ok, t()} | {:error, term()}
```

A utility for parsing sorts provided from external input. Only allows sorting on public fields.

See `Ash.Query.sort/3` for supported formats.

## Handling specific values

A handler function may be provided that takes a string, and returns the relevant sort
It won't be given any prefixes, only the field. This allows for things like parsing the calculation values
out of the sort, or setting calculation values if they are not included in the sort string.

To return calculation parameters, return `{:field, %{param: :value}}`. This will end up as something
like `{:field, {%{param: :value}, :desc}}`, with the corresponding sort order.

This handler function will only be called if you pass in a string or list of strings for the sort.
Atoms will be assumed to have already been handled. The handler should return `nil` if it is not handling
the given field.

# `parse_input!`

Same as `parse_input/2` except raises any errors

See `parse_input/2` for more.

# `parse_sort`

# `reverse`

Reverses an Ash sort statement.

# `runtime_sort`

A utility for sorting a list of records at runtime.

For example:

    Ash.Sort.runtime_sort([record1, record2, record3], name: :asc, type: :desc_nils_last)

Keep in mind that it is unrealistic to expect this runtime sort to always
be exactly the same as a sort that may have been applied by your data layer.
This is especially true for strings. For example, `Postgres` strings have a
collation that affects their sorting, making it unpredictable from the perspective
of a tool using the database: https://www.postgresql.org/docs/current/collation.html

---

*Consult [api-reference.md](api-reference.md) for complete listing*
