# `Masu.Filter`
[🔗](https://github.com/hattoriai/masu/blob/v0.7.0/lib/masu/filter.ex#L1)

A condition on a column that a row must meet to be in the grid.

`op` is one of:

  * `:eq` and `:neq`: equal, or not, to `value`;
  * `:contains`, `:not_contains`, `:starts_with` and `:ends_with`: for
    text, without case;
  * `:gt`, `:gte`, `:lt` and `:lte`: greater or less than `value`;
  * `:between`: from the first to the second value of a two-item list,
    both included;
  * `:in`: one of the values of a list;
  * `:is_nil` and `:not_nil`: no value, or any value (with no `value`).

A column of many values (a path through several related rows, see
`Masu.Column`) filters by `:in` ("has any of" the values), `:all_of`
("has all of"), `:none_of` ("has none of"), `:is_nil` ("has none":
no related row) and `:not_nil` ("has some").

The value is read for the column's type (see `Masu.Column`): a date
column takes `"2026-10-17"` or a `Date`, a number column `"12.5"` or
`12.5`.

# `op`

```elixir
@type op() ::
  :eq
  | :neq
  | :contains
  | :not_contains
  | :starts_with
  | :ends_with
  | :gt
  | :gte
  | :lt
  | :lte
  | :between
  | :in
  | :is_nil
  | :not_nil
  | :all_of
  | :none_of
```

# `t`

```elixir
@type t() :: %Masu.Filter{key: String.t(), op: op(), value: term()}
```

# `cast`

```elixir
@spec cast(t(), [Masu.Column.t()]) :: {:ok, t()} | {:error, String.t()}
```

Checks a filter against the grid's columns and reads its value for the
column's type. Returns the filter with the value read, or an error that
says why: no such column, a column that does not filter, an operator
that is not for its type, or a value it cannot read. A value is an
error too when a text of it is over 1,000 bytes or has a NUL
character, or a list filter has more than 10,000 values.

# `many_ops`

```elixir
@spec many_ops() :: [op()]
```

The operators of a filter on a column of many values (`Masu.Column.many?/1`).

# `match?`

```elixir
@spec match?(t(), term()) :: boolean()
```

Whether a value meets the filter, as `Masu.Source.List` checks it. The
filter's value must already be read (`cast/2`).

# `match_many?`

```elixir
@spec match_many?(t(), [term()] | nil) :: boolean()
```

Whether the values of a column of many values (a list, or nil: not
loaded) meet the filter, as `Masu.Source.List` checks them.

# `new`

```elixir
@spec new(String.t() | atom(), op(), term()) :: t()
```

A filter on the column with `key`.

# `ops`

```elixir
@spec ops() :: [op()]
```

The operators of a filter.

# `ops`

```elixir
@spec ops(Masu.Column.type()) :: [op()]
```

The operators of a filter on a column of `type`: those of text only for text and enums.

---

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