ExGram.Router.Dsl (ex_gram_router v0.1.0)

Copy Markdown View Source

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.

Summary

Functions

Registers a short atom alias for a filter module.

Adds a filter to the current scope.

Sets the handler for the current scope.

Opens a new routing scope. A scope can contain

Functions

alias_filter(module, list)

(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(module_or_alias, opts \\ nil)

(macro)

Adds a filter to the current scope.

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(func)

(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(list)

(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.