ruma_common::api

Attribute Macro request

Source
#[request]
Available on crate feature api only.
Expand description

Generates OutgoingRequest and IncomingRequest implementations.

The OutgoingRequest impl is on the Request type this attribute is used on. It is feature-gated behind cfg(feature = "client").

The IncomingRequest impl is on IncomingRequest, which is either a type alias to Request or a fully-owned version of the same, depending of whether Request has any lifetime parameters. It is feature-gated behind cfg(feature = "server").

The generated code expects a METADATA constant of type Metadata to be in scope, alongside a Response type that implements OutgoingResponse (for cfg(feature = "server")) and / or IncomingResponse (for cfg(feature = "client")).

By default, the type this macro is used on gets a #[non_exhaustive] attribute. This behavior can be controlled by setting the ruma_unstable_exhaustive_types compile-time cfg setting as --cfg=ruma_unstable_exhaustive_types using RUSTFLAGS or .cargo/config.toml (under [build] -> rustflags = ["..."]). When that setting is activated, the attribute is not applied so the type is exhaustive.

§Attributes

To declare which part of the request a field belongs to:

  • #[ruma_api(header = HEADER_NAME)]: Fields with this attribute will be treated as HTTP headers on the request. The value must implement ToString and FromStr. Generally this is a String. The attribute value shown above as HEADER_NAME must be a const expression of the type http::header::HeaderName, like one of the constants from http::header, e.g. CONTENT_TYPE. During deserialization of the request, if the field is an Option and parsing the header fails, the error will be ignored and the value will be None.
  • #[ruma_api(path)]: Fields with this attribute will be inserted into the matching path component of the request URL. If there are multiple of these fields, the order in which they are declared must match the order in which they occur in the request path.
  • #[ruma_api(query)]: Fields with this attribute will be inserting into the URL’s query string.
  • #[ruma_api(query_all)]: Instead of individual query fields, one query_all field, of any type that can be (de)serialized by serde_html_form, can be used for cases where multiple endpoints should share a query fields type, the query fields are better expressed as an enum rather than a struct, or the endpoint supports arbitrary query parameters.
  • No attribute: Fields without an attribute are part of the body. They can use #[serde] attributes to customize (de)serialization.
  • #[ruma_api(body)]: Use this if multiple endpoints should share a request body type, or the request body is better expressed as an enum rather than a struct. The value of the field will be used as the JSON body (rather than being a field in the request body object).
  • #[ruma_api(raw_body)]: Like body in that the field annotated with it represents the entire request body, but this attribute is for endpoints where the body can be anything, not just JSON. The field type must be Vec<u8>.

§Examples

pub mod do_a_thing {
    use ruma_common::{api::request, OwnedRoomId};

    // const METADATA: Metadata = metadata! { ... };

    #[request]
    pub struct Request {
        #[ruma_api(path)]
        pub room_id: OwnedRoomId,

        #[ruma_api(query)]
        pub bar: String,

        #[serde(default)]
        pub foo: String,
    }

    // #[response]
    // pub struct Response { ... }
}

pub mod upload_file {
    use http::header::CONTENT_TYPE;
    use ruma_common::api::request;

    // const METADATA: Metadata = metadata! { ... };

    #[request]
    pub struct Request {
        #[ruma_api(path)]
        pub file_name: String,

        #[ruma_api(header = CONTENT_TYPE)]
        pub content_type: String,

        #[ruma_api(raw_body)]
        pub file: Vec<u8>,
    }

    // #[response]
    // pub struct Response { ... }
}

⚠ If this is the only documentation you see, please navigate to the docs for ruma_common::api::request, where actual documentation can be found.