# `Monty.ModuleMap.Table`
[🔗](https://github.com/d-led/ex.tbp.monty/blob/v0.1.0/packages/ex_tbp_monty_core/lib/monty/module_map/table.ex#L1)

The map as `/modules` reads it: one row per class, with the two files a reader
wants to open and the one fact the map alone cannot show.

Every row is the generated map (`Monty.ModuleMap.Data`) — the class, the
Elixir module the rule gives it, and its status — so the page cannot drift
from `mix monty.module_map.verify`. What is added here is only what follows
from that data: the upstream file at the commit the map records, this
repository's file for the module an implemented class lives in, and the
stand-in the map carries for a class the runtime replaces.

A row is filterable by *any word in it*: the text searched is every field
joined, so `camera implemented`, `graph_matching planned` and `runtime` all
find what a reader means without a column being named.

# `row`

```elixir
@type row() :: %{
  id: String.t(),
  package: String.t(),
  class: String.t(),
  file: String.t(),
  python_url: String.t() | nil,
  monty_test_url: String.t() | nil,
  elixir: String.t(),
  elixir_url: String.t() | nil,
  test_url: String.t() | nil,
  status: :implemented | :partial | :planned | :excluded,
  reason: String.t() | nil,
  stand_ins: [map()],
  text: String.t()
}
```

One class, as a row of the table.

`elixir_url` is nil for a class this application has not written: there is no
file to open, and the name is the contract for the file there will be.

# `describe`

```elixir
@spec describe(map()) :: String.t()
```

What a stand-in is called, as the table prints it.

# `filter`

```elixir
@spec filter([row()], String.t() | nil, atom() | nil) :: [row()]
```

The rows matching a query and a status.

`query` is any whitespace-separated words, each of which has to appear
somewhere in the row; `status` is `:all` (or nil) or one of the map's
statuses. Both are the page's URL state, so the same view can be linked to.

# `rows`

```elixir
@spec rows(keyword()) :: [row()]
```

The rows, in the map's own order.

Options: `:repo` — this repository's URL, which is what the "our file" links
hang off — and `:revision`, the commit they point at (a release knows its own;
a checkout that was never built links to `main`).

# `status`

```elixir
@spec status(String.t() | atom() | nil) :: atom()
```

The status a page should filter by, from what the URL said.

A query string is not trusted with an atom: an unknown word is no filter at
all, which shows everything and cannot crash a page.

# `statuses`

```elixir
@spec statuses() :: [atom()]
```

The statuses a row can have, in the order the page offers them.

---

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