df_st_api 0.3.0-development-1

Starting an API server for the DF Storyteller project.
Documentation
use failure::Error;
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
use rocket::request::{FromQuery, Query};
use df_rocket_okapi::{
    gen::OpenApiGenerator, request::get_nested_query_parameters, request::OpenApiFromQuery,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;

/// A Query Guard for querying of one item.
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
pub struct ApiItemQuery {
    /// Don't load nested items. This will speed up page loads but will not fill in all the data.
    /// Fields that can be used for ordering are usually the only field that are returned.
    /// - `Some(false)` If value is not set, or set to "false" or "0" (same result default)
    /// - `Some(true)` If value is set to ""(empty), "true" or "1"
    /// - `None` If any other value this will add all the data to the response (default)
    pub minimal_data: Option<bool>,
}

/// Parse incoming query data and store in `ApiPagination`
impl<'q> FromQuery<'q> for ApiItemQuery {
    type Error = Error; //TODO Custom error

    fn from_query(query: Query<'q>) -> Result<Self, Self::Error> {
        let mut api_item_request = ApiItemQuery::default();
        for key in query {
            #[allow(clippy::single_match)]
            match key.key.url_decode()?.as_ref() {
                "minimal_data" => {
                    info!("minimal_data: {:?}", key.value.url_decode_lossy());
                    api_item_request.minimal_data = match key.value.url_decode_lossy().as_ref() {
                        "true" | "1" | "" => Some(true),
                        "false" | "0" => Some(false),
                        x => {
                            error!(
                                "Field `minimal_data` uses unknown value `{}`. \
                                Please use `true`, `1`, `false` or `0`.",
                                x
                            );
                            None
                        }
                    }
                }
                _ => {}
            }
        }
        Ok(api_item_request)
    }
}

/// Add support for OpenApi generator
impl<'r> OpenApiFromQuery<'r> for ApiItemQuery {
    fn query_multi_parameter(
        gen: &mut OpenApiGenerator,
        name: String,
        required: bool,
    ) -> df_rocket_okapi::Result<Vec<okapi::openapi3::Parameter>> {
        Ok(get_nested_query_parameters::<ApiItemQuery>(
            gen, name, required,
        ))
    }
}