# `ExGram.Router.Dsl`
[🔗](https://github.com/rockneurotiko/ex_gram_router/blob/v0.1.0/lib/ex_gram/router/dsl.ex#L1)

Compile-time DSL macros for building the routing tree.

These macros are imported automatically when you `use ExGram.Router`.
You should not need to import this module directly.

## How the scope stack works

During compilation, a module attribute `@__exgram_scope_stack__` acts as a
stack of "in-progress" scopes. When `scope do ... end` is entered, a new
empty scope is pushed. The block body runs (adding filters, handlers, or
nested scopes). When the block ends, the completed scope is popped and
either attached to the parent scope (as a child) or registered as a
top-level scope.

The final list of top-level scopes is stored in `@__exgram_scopes__` and
consumed by `ExGram.Router.Compiler` in the `@before_compile` hook.

# `alias_filter`
*macro* 

Registers a short atom alias for a filter module.

## Example

    alias_filter ExGram.Router.Filters.Command, as: :command
    alias_filter ExGram.Router.Filters.Text, as: :text
    alias_filter MyApp.Filters.State, as: :state

After this, you can use the alias in `filter` calls:

    filter :command, :start
    filter :state, :registration

# `filter`
*macro* 

Adds a filter to the current scope.

## Atom alias form (recommended)

    filter :command, :start
    filter :text

## Module form

    filter MyApp.Filters.AdminOnly
    filter MyApp.Filters.State, :registration

The atom alias must have been registered via `alias_filter/2`.

# `handle`
*macro* 

Sets the handler for the current scope.

Accepts a function capture of arity 1 or 2, or an anonymous function:
- Arity 1: `&MyMod.fun/1`, `&my_local_fun/1`, or `fn context -> ... end` - receives only the context
- Arity 2: `&MyMod.fun/2`, `&my_local_fun/2`, or `fn update_info, context -> ... end` - receives
  `(update_info, context)`, same as ExGram's `handle/2`

Local captures (`&my_fun/1`) support both public (`def`) and private (`defp`) functions.

## Examples

    handle &MyBot.start/1
    handle &MyBot.handle_text/2
    handle &my_local_handler/1

    handle fn context ->
      context |> answer("Hello!")
    end

    handle fn update_info, context ->
      context
    end

# `scope`
*macro* 

Opens a new routing scope. A scope can contain:
- `filter` declarations (zero or more)
- `handle` (exactly one, for leaf scopes)
- Nested `scope` blocks (for branch scopes)

A scope must have either a `handle` OR nested `scope` blocks, not both.

---

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