Expand description
Router combines all event observers.
Each event observer is a special unit that handles a specific event type. There are two types of event observers:
- Simple observer:
Simple observer
is used to handle simple events like startup and shutdown. When you register a handler in this observer, you specify the arguments that pass to the handler when the event is trigger. Return type of the handler is [Result<(), HandlerError>
]. When observer is trigger, it calls all handlers in order of registration and stops if one of them returns an error.
Registration of the handlers looks like this:
async fn on_startup(message: &str) -> HandlerResult {
...
}
async fn on_shutdown(message: &str) -> HandlerResult {
...
}
let mut router = Router::new("example");
router.startup.register(on_startup, ("Hello, world!",));
router.shutdown.register(on_shutdown, ("Goodbye, world!",));
- Telegram observer:
Telegram observer
is used to handle telegram events like messages, callback queries, polls and all other event types. You can register a handler with any arguments that implementFromEventAndContext
trait, seeextractors module
for more details. Return type of the handler isResult<EventReturn, HandlerError>
, whereEventReturn
is a special enum that can be used to control the propagation of the event, seeEventReturn
for more details. When observer is trigger, it calls outer middlewares and checks all handlers in order of registration. It calls all filters for each handler and skips the handler if one of them returnsfalse
. If the handler is pass the filters, observer calls inner middlewares and the handler itself (in the middleware). By default, the first handler that pass the filters stop the propagation of the event, so other handlers aren’t calls. (You can change this behaviour by specify another variant ofEventReturn
).
Registration of the handlers looks like this:
async fn on_message(message: Message) -> HandlerResult {
...
}
async fn on_callback_query(callback_query: CallbackQuery) -> HandlerResult {
...
}
let mut router = Router::new("example");
router.message.register(on_message);
router.callback_query.register(on_callback_query);
Routers can be nested, so you can create a tree of routers using Router::include_router
method.
You can use Router::include_router
method to include a router to the current router as sub router.
Inner middlewares of the parent router will be registered to the sub router and its sub routers in the order of registration.
Parent middlewares registers on the top of the stack, so parent middlewares calls before.
OuterMiddlewaresConfig
and InnerMiddlewaresConfig
are used to configure outer and inner middlewares, respectively,
or just use OuterMiddlewaresConfigBuilder
and InnerMiddlewaresConfigBuilder
to create a config step by step.
You can use OuterMiddlewaresConfig::default
and InnerMiddlewaresConfig::default
to create a default config
with LoggingMiddleware
to log all incoming updates and UserContextMiddleware
to set up user context.
All config middlewares are registered in the order of registration and before other middlewares.
You can propagate event with calls PropagateEvent::propagate_event
or PropagateEvent::propagate_update_event
,
PropagateEvent::emit_startup
, PropagateEvent::emit_shutdown
methods in Router
,
but it’s better to use Dispatcher
that does it for you.
Order of event propagation when propagate event is called for router:
- Call outer middlewares of update observer in order of registration;
1.1) If middleware returnsEventReturn::Finish
, then updateRequest
because the middleware could have changed it and go to the 1 step;
1.2) If middleware returnsEventReturn::Skip
, then skip this middleware and go to the 1 step;
1.3) If middleware returnsEventReturn::Cancel
, then cancel propagation of outer middlewares of update observer and go to the 2 step;
1.4) If all middlewares by step 1.1 are passed or skipped on 1.2 or propagation cancelled by step 1.3, then go to the 2 step; - Call filters of handlers of update observer in order of registration;
2.1) If one of the handler filters returnsfalse
, then skip the handler and go back to the 2 step;
2.2) If any handler filter returnstrue
, then go to the 3 step;
2.3) If all handlers are skipped on 2.1, then go to the 4 step; - Call inner middlewares of update observer and the handler itself (handler is called in the middleware);
3.1) If the handler or middleware returnsEventReturn::Skip
, then we should skip it and go to the 3 step;
3.2) If the handler or middleware returnsEventReturn::Cancel
, then we should stop propagation of innder middlewares of update observer and go to the 4 step;
3.3) If the handler or middleware returnsEventReturn::Finish
, then we should stop propagation and return a response and go to the 4 step;
3.4) If the handler of middleware returns error, then we should stop propagation and return a response because the error is the correct result from the point of view of observer and go to the 4 step;
3.5) If all handlers or middlewares are skipped on 3.1, then go to the 4 step; - Stop propagation of update observer;
- Check which observer respond to the current
UpdateType
; - Call outer middlewares of the observer in order of registration;
6.1) If middleware returnsEventReturn::Finish
, then updateRequest
because the middleware could have changed it and go to the 6 step;
6.2) If middleware returnsEventReturn::Skip
, then skip this middleware and go to the 6 step;
6.3) If middleware returnsEventReturn::Cancel
, then cancel event propagation and go to the 10 step;
6.4) If all middlewares by step 1.1 are passed or skipped on 1.2, then go to the 7 step; - Call filters of handlers of the observer in order of registration;
7.1) If one of the handler filters returnsfalse
, then skip the handler and go back to the 7 step;
7.2) If any handler filter returnstrue
, then go to the 8 step;
7.3) If all handlers are skipped on 7.1, then cancel propagation of the observer and go to the 9 step; - Call inner middlewares of the observer and the handler itself (handler is called in the middleware);
8.1) If the handler or middleware returnsEventReturn::Skip
, then we should skip it and go to the 8 step;
8.2) If the handler or middleware returnsEventReturn::Cancel
, then we should stop propagation of the observer and go to the 10 step;
8.3) If the handler or middleware returnsEventReturn::Finish
, then we should stop propagation and return a response and go to the 10 step;
8.4) If the handler of middleware returns error, then we should stop propagation and return a response because the error is the correct result from the point of view of observer and go to the 10 step;
8.5) If all handlers or middlewares are skipped on 8.1, then go to the 9 step; - Check to which router from current router’s sub routers propagate event next;
9.1) If there is no sub routers, then go to the 10 step;
9.2) If there is sub routers, then go to the 1 step for the first sub router;
9.2.1) If the propagate eventPropagateEventResult::Unhandled
by the sub router’s observer, then go to the 9 step;
9.2.2) If the propagate eventPropagateEventResult::Handled
by the sub router’s observer, then go to the 10 step;
9.2.3) If the propagate eventPropagateEventResult::Rejected
, then return an unhandled response and go to the 10 step; - Finish event propagation.
Structs§
- Router combines all event observers.