macro_rules! endpoint {
    {
        $method:ident $path:tt,
        #[$payload:ident $($auth:ident)?] $typ:ty,
        $(#[$out_res:ident])? $out:ty
    } => { ... };
    { @path ($path:expr, $($arg:ident),+) } => { ... };
    { @path $path:expr } => { ... };
    { @payload query } => { ... };
    { @payload body } => { ... };
    { @payload no_data } => { ... };
    { @auth } => { ... };
    { @send, $typ:ty, $out:ty } => { ... };
    { @send:flatten_result, $typ:ty, $out:ty } => { ... };
    { @send:discard_result, $typ:ty, $out:ty } => { ... };
    { @send:no_send, $typ:ty, $out:ty } => { ... };
}
Expand description

Helper macro to quickly implement the Endpoint trait, and optionally a send() method for the input struct.

The arguments are ordered as follows:

  1. HTTP method and endpoint path.
  2. Input data to serialize unless no_data is specified.
  3. Response struct to deserialize into.

with the following format:

  1. <HTTP Method> “<ENDPOINT PATH>”
  2. #[<ATTRIBUTE>] <INPUT STRUCT>
  3. #[<OPTIONAL ATTRIBUTE>] <OUTPUT STRUCT>

The endpoint is specified by the HTTP method, followed by the path. To get a dynamic path based on the input structure, surround the path with parenthesis:

POST ("/account/activate/{}", id)

The format is the same as the format!() macro, except id will be substituted by self.id, where self represents an instance of the second parameter.

The input structure is preceded by an attribute-like structure.

  • query: The input structure will be serialized as the query string.
  • body: The input structure will be serialized as a JSON body.
  • no_data: No data will be sent with the request.
  • auth: If this is included, the request will not be made if the user is not authenticated.

Some examples of valid tags are:

#[query] QueryReq
#[body] BodyReq
#[query auth] QueryReq
#[no_data] QueryStruct

The input structure itself should implement serde::Serialize if it is used as a body or query.

The third argument is the output type, tagged similarly to the input, to modify the behaviour of the generated send() method.

  • <no tag>: send() will simply return Result<Output>.
  • flatten_result: If Output = Result<T>, the return type will be simplified to Result<T>.
  • discard_result: If Output = Result<T>, discard T, and return Result<()>.
  • no_send: Do not implement a send() function.

Examples

endpoint! {
    GET "/path/to/endpoint", // Endpoint.
    #[query] StructWithData<'_>, // Input data; this example will be serialized as a query string.
    #[flatten_result] Result<ResponseType> // Response struct; this example will return `Ok(res)` or `Err(e)` instead of `Result<ResponseType>` because of `#[flatten_result]`.
}