df_st_api 0.3.0-development-2

Starting an API server for the DF Storyteller project.
use crate::api_errors::APIErrorNotModified;
use crate::api_objects::ApiObject;
use crate::pagination::{ApiPage, ApiPagination};
use crate::DfStDatabase;
use crate::ServerInfo;
use df_rocket_okapi_codegen::openapi;
use df_st_db::{id_filter, DBObject};
use rocket::{get, State};
use rocket_contrib::json::Json;

impl ApiObject for df_st_core::LinkHEHF {
    fn get_type() -> String {
        "link_he_hf".to_owned()
    }
    fn get_item_link(&self, base_url: &str) -> String {
        format!(
            "{}/link_he_hf?he_id={}&hf_id={}",
            base_url, self.he_id, self.hf_id
        )
    }
    fn get_page_link(base_url: &str) -> String {
        format!("{}/link_he_hf", base_url)
    }
    fn get_count_link(base_url: &str) -> String {
        format!("{}/link_he_hf/count", base_url)
    }
}

/// Request a list of all `LinkHEHF` in the world.
/// You can filter on `he_id` or `hf_id`.
///
/// ( Since = "0.1.2" )
#[openapi]
#[get("/link_he_hf?<he_id>&<hf_id>&<pagination..>")]
pub fn list_link_he_hf(
    conn: DfStDatabase,
    pagination: ApiPagination,
    server_info: State<ServerInfo>,
    he_id: Option<i32>,
    hf_id: Option<i32>,
) -> Result<Json<ApiPage<df_st_core::LinkHEHF>>, APIErrorNotModified> {
    let mut api_page = ApiPage::<df_st_core::LinkHEHF>::new(&pagination, &server_info);
    api_page.match_fields::<df_st_db::LinkHEHF, _, _>()?;

    // Add optional items to id_filter.
    let mut id_filter = id_filter!["world_id" => server_info.world_id];
    if let Some(he_id) = he_id {
        id_filter.insert("he_id".to_owned(), he_id);
    }
    if let Some(hf_id) = hf_id {
        id_filter.insert("hf_id".to_owned(), hf_id);
    }
    api_page.total_item_count = df_st_db::LinkHEHF::get_count_from_db(
        &*conn,
        api_page.add_int_filter(id_filter.clone()),
        api_page.get_string_filter(),
        0,
        1,
        None,
        None,
    )
    .unwrap() // TODO These errors should be better handled
    .get(0)
    .unwrap()
    .count;

    let result_list = df_st_db::LinkHEHF::get_list_from_db(
        &*conn,
        api_page.add_int_filter(id_filter),
        api_page.get_string_filter(),
        api_page.page_start,
        api_page.max_page_size,
        api_page.get_db_order(),
        api_page.order_by.clone(),
        None,
        api_page.get_nested_items(),
    )
    .unwrap(); // TODO These errors should be better handled

    if api_page.wrap(result_list) {
        return Err(APIErrorNotModified::new());
    }
    Ok(Json(api_page))
}

/// Request a list of all `HistoricalEvent` here a `HistoricalFigure` was mentioned.
///
/// ( Since = "0.1.2" )
#[openapi]
#[get("/link_he_hf/<hf_id>?<pagination..>")]
pub fn list_he_from_hf(
    conn: DfStDatabase,
    pagination: ApiPagination,
    server_info: State<ServerInfo>,
    hf_id: i32,
) -> Result<Json<ApiPage<df_st_core::HistoricalEvent>>, APIErrorNotModified> {
    let mut api_page = ApiPage::<df_st_core::HistoricalEvent>::new(&pagination, &server_info);
    api_page.match_fields::<df_st_db::HistoricalEvent, _, _>()?;

    // Request all Links
    let result_links = df_st_db::LinkHEHF::get_list_from_db(
        &*conn,
        api_page.add_int_filter(id_filter!["world_id" => server_info.world_id, "hf_id" => hf_id]),
        api_page.get_string_filter(),
        api_page.page_start,
        api_page.max_page_size,
        api_page.get_db_order(),
        api_page.order_by.clone(),
        None,
        false,
    )
    .unwrap();
    // Put all the id in a list
    let id_list: Vec<i32> = result_links.iter().map(|item| item.he_id).collect();

    // Request the correct HistoricalEvents.
    api_page.total_item_count = df_st_db::HistoricalEvent::get_count_from_db(
        &*conn,
        api_page.add_int_filter(id_filter!["world_id" => server_info.world_id]),
        api_page.get_string_filter(),
        0,
        1,
        None,
        Some(id_list.clone()),
    )
    .unwrap() // TODO These errors should be better handled
    .get(0)
    .unwrap()
    .count;

    let result_list = df_st_db::HistoricalEvent::get_list_from_db(
        &*conn,
        api_page.add_int_filter(id_filter!["world_id" => server_info.world_id]),
        api_page.get_string_filter(),
        api_page.page_start,
        api_page.max_page_size,
        api_page.get_db_order(),
        api_page.order_by.clone(),
        Some(id_list),
        api_page.get_nested_items(),
    )
    .unwrap(); // TODO These errors should be better handled

    if api_page.wrap(result_list) {
        return Err(APIErrorNotModified::new());
    }
    Ok(Json(api_page))
}