# `DDD.Listing`
[🔗](https://github.com/blackuprise/vicander/blob/v0.1.1/lib/ddd/use_cases/listing.ex#L1)

The listing functions shared by repository adapters (`DDD.Repository.Ecto`) and projections
(`DDD.Projection`): `list/1`, `page/1`, `slice/1` and `count/1`.

Options (all optional):

  * `:filter` - a `DDD.Filter` expression
  * `:spec` - a `DDD.Specification` (one that defines `to_filter/1`); combined with `:filter`
  * `:order` - `:title`, `{:desc, :title}` or `[desc: :created_at, asc: :title]`. The primary
    key is always added as the last tie-breaker, so the order is total and pages are stable.
    Default: the primary key.
  * `list/1`: `:limit` (default: all)
  * `page/1`: `:page` (default 1), `:page_size` (default 20, at most 1000)
  * `slice/1`: `:limit` (default 20, at most 1000), `:after` (a `DDD.Slice`'s `next_cursor`)

Everything returns `{:ok, result}` or `{:error, %DDD.Error{kind: :business}}` with the code
`:invalid_filter`, `:invalid_order`, `:invalid_page` or `:invalid_cursor`: these options often
come straight from a client's request, so a bad one is an answer, not a crash.

# `count`

```elixir
@spec count(ctx(), keyword()) :: {:ok, non_neg_integer()} | {:error, DDD.Error.t()}
```

# `list`

```elixir
@spec list(ctx(), keyword()) :: {:ok, [term()]} | {:error, DDD.Error.t()}
```

# `page`

```elixir
@spec page(ctx(), keyword()) :: {:ok, DDD.Page.t()} | {:error, DDD.Error.t()}
```

# `slice`

```elixir
@spec slice(ctx(), keyword()) :: {:ok, DDD.Slice.t()} | {:error, DDD.Error.t()}
```

---

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