Learning Rust I met a rigid, statically typed language. Specifically it has no function overloading or optional function parameters.
In the example we have a trigger method that receives a Context object and a function pointer. The function pointer might receive 1 or 2 parameters of the Id or Param types. Magic?
The Context is the received state, Request in Axums case. This is the source of the "parts" our functions want to receive. In this simplified example it contains two data fields
The first trick is the FromContext trait. It will allow us to create "Extractors" that extract the necessary data from the context object. For example
The second trick is the Handler trait. We will implement the trait for the closure type Fn(T). Yeah we can implement traits for closure types. This implementation will allow us to have a "middleware" between the function call and its arguments. Here we will call the FromContext::from_context method, converting the context to the expected function argument i.e Param or Id.
To Support multiple function parameters we'll go ahead and implement Handler for closure types with 2, 3, 4 and so on parameters. An interesting point here is that this implementation is agnostic to the order of the parameters - it will support both fn foo(p: Param, id: Id) and fn foo(id: Id, p: Param)!