# `Ash.Info.Manifest.Generator.OperatorResolver`
[🔗](https://github.com/ash-project/ash/blob/v3.27.8/lib/ash/info/manifest/generator/operator_resolver.ex#L5)

Resolves which predicate operators and functions in the filter capabilities
catalog apply to a given field type, pre-resolving the right-hand-side type
for each match.

Treats the field as the *first argument* of each operator/function signature.
`:any` and `:same` arg-kind sentinels always match. Concrete builtins match
when the type's `kind` agrees; concrete modules match when the type's
`module` agrees. `Ash.Type.operator_overloads/0` is consulted for the
type's module — any operator listed there is considered applicable.

## NewType subtype matching

When the field's type module is an `Ash.Type.NewType`, applicability is
evaluated against both the NewType and its `subtype_of/0` base type. This
mirrors how ash_graphql derives filter inputs for NewType fields — operators
with concrete signatures (e.g. `:contains` requires `:string`) match the
underlying base.

## Ordered comparison trimming

For `:array`- and `:boolean`-kind field types, ordered comparison
operators (`:<`, `:>`, `:<=`, `:>=`) are dropped from the result. They
survive the structural signature match (their sigs are `[:same, :any]`,
which accepts anything) but the orderings aren't useful: no common Ash
data layer offers a meaningful whole-array compare (Postgres'
lexicographic compare is rarely what users want, Ets has no notion at
all), and booleans have no meaningful ordering for filter UX. Equality,
membership, and `is_nil` are preserved.

## RHS resolution

For each applicable entry, the matching signature's *second* arg drives the
`rhs` value on the returned `%ApplicableOperator{}`/`%ApplicableFunction{}`.
Single-arg signatures (e.g. `Eq`'s `[:any]` and `[:same]` shorthand) yield
`rhs: :same`. Multi-arg signatures yield:

  * second arg `:same`        → `:same`
  * second arg `:any`         → `:any`
  * second arg concrete       → `{:concrete, type_ref}`
  * second arg `{:array, t}`  → `{:array, rhs(t)}`

Operators that apply only via `operator_overloads/0` (no matching signature
found structurally) default to `rhs: :same`.

# `resolve`

```elixir
@spec resolve(
  Ash.Info.Manifest.Type.t(),
  Ash.Info.Manifest.FilterCapabilities.t(),
  module() | nil
) ::
  {[Ash.Info.Manifest.ApplicableOperator.t()],
   [Ash.Info.Manifest.ApplicableFunction.t()]}
```

Resolve applicable operators and functions for a field type.

Returns `{[ApplicableOperator.t()], [ApplicableFunction.t()]}` — each entry
pairs an operator/function name with its pre-resolved right-hand-side type.

When `resource_data_layer` is given, data-layer-tagged functions
(`%Function{data_layer_module: dl}` with `dl != nil`) are filtered to only
those whose `data_layer_module` matches. Untagged (builtin) functions are
always considered. Pass `nil` to hide all data-layer-tagged functions —
use the default `resolve/2` when there's no data-layer context.

# `resolve_custom_expressions`

```elixir
@spec resolve_custom_expressions(
  Ash.Info.Manifest.Type.t(),
  Ash.Info.Manifest.FilterCapabilities.t()
) ::
  [Ash.Info.Manifest.ApplicableCustomExpression.t()]
```

Resolve applicable custom expressions for a field type.

Same shape as the operator/function resolution but against
`caps.custom_expressions` filtered by `predicate_custom_expressions`.
Returns a list of `%ApplicableCustomExpression{}`.

---

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