Derive Macro to_query_params::QueryParams

source ·
#[derive(QueryParams)]
{
    // Attributes available to this derive:
    #[query]
}
Expand description

QueryParams derives fn to_query_params(&self) -> Vec<(String, String)> for any struct with field values supporting .to_string().

Optional values are only included if present, and fields marked #[query(required)] must be non-optional. Renaming and excluding of fields is also available, using #[query(rename = "new_name")] or #[query(exclude)] on the field.

Example: Query Params

QueryParams supports both required and optional fields, which won’t be included in the output if their value is None.

// Eq and PartialEq are just for assertions
#[derive(QueryParams, Debug, PartialEq, Eq)]
struct ProductRequest {
    #[query(required)]
    id: i32,
    min_price: Option<i32>,
    max_price: Option<i32>,
}

pub fn main() {
    let request = ProductRequest {
        id: 999, // will be included in output
        min_price: None, // will *not* be included in output
        max_price: Some(100), // will be included in output
    };

    let expected = vec![
        ("id".into(), "999".into()),
        ("max_price".into(), "100".into())
    ];
     
    let query_params = request.to_query_params();

    assert_eq!(expected, query_params);
}

Attributes

QueryParams supports attributes under #[query(...)] on individual fields to carry metadata. At this time, the available attributes are:

  • required – marks a field as required, meaning it can be T instead of Option<T> on the struct and will always appear in the resulting Vec
  • rename – marks a field to be renamed when it is output in the resulting Vec. E.g. #[query(rename = "newName")]
  • exclude – marks a field to never be included in the output query params

Example: Renaming and Excluding

In some cases, names of query parameters are not valid identifiers, or don’t adhere to Rust’s default style of “snake_case”. QueryParams can rename individual fields when creating the query parameters Vec if the attribute with the rename attribute: #[query(rename = "new_name")].

In the below example, an API expects a type of product and a max price, given as type=something&maxPrice=123, which would be and invalid identifier and a non-Rust style field name respectively. A field containing local data that won’t be included in the query is also tagged as #[query(exclude)] to exclude it.

// Eq and PartialEq are just for assertions
#[derive(QueryParams, Debug, PartialEq, Eq)]
struct ProductRequest {
    #[query(required)]
    id: i32,
    #[query(rename = "type")]
    product_type: Option<String>,
    #[query(rename = "maxPrice")]
    max_price: Option<i32>,
    #[query(exclude)]
    private_data: i32,
}

pub fn main() {
    let request = ProductRequest {
        id: 999,
        product_type: Some("accessory".into()),
        max_price: Some(100),
        private_data: 42, // will not be part of the output
    };

    let expected = vec![
        ("id".into(), "999".into()),
        ("type".into(), "accessory".into()),
        ("maxPrice".into(), "100".into())
    ];
     
    let query_params = request.to_query_params();

    assert_eq!(expected, query_params);
}