use crate::api_objects::ApiObject;
use crate::pagination::{ApiItemQuery, ApiPage};
use crate::ServerInfo;
use df_st_core::SchemaExample;
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
use rocket::State;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
#[schemars(example = "Self::example")]
pub struct ApiItem<D>
where
D: ApiObject + Serialize + SchemaExample,
{
#[serde(rename = "_type")]
pub type_: String,
#[serde(rename = "_links")]
pub links: ApiItemLinks,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "_minimal_data")]
pub minimal_data: Option<bool>,
#[serde(flatten)]
pub data: D,
#[serde(skip)]
pub base_url: String,
}
impl<D> SchemaExample for ApiItem<D>
where
D: SchemaExample + Serialize + ApiObject,
{
fn example() -> Self {
Self {
type_: D::get_type(),
links: ApiItemLinks {
self_: Some(D::example().get_item_link(&"http://127.0.0.1:20350/api".to_owned())),
},
minimal_data: Some(false),
data: D::example(),
base_url: "".to_owned(),
}
}
}
impl<D> ApiItem<D>
where
D: ApiObject + Default + Serialize + SchemaExample,
{
pub fn new(server_info: &State<ServerInfo>, item_query: &ApiItemQuery) -> Self {
let server_info = server_info.inner().clone();
Self {
minimal_data: item_query.minimal_data,
base_url: server_info.base_url,
..Default::default()
}
}
fn set_links(&mut self) {
let mut query_parameters = Vec::new();
if let Some(minimal_data) = &self.minimal_data {
query_parameters.push(format!("minimal_data={}", minimal_data));
}
let mut links = ApiItemLinks::default();
let base_api_path = self.data.get_item_link(&self.base_url);
if query_parameters.is_empty() {
links.self_ = Some(base_api_path);
} else {
links.self_ = Some(format!("{}?{}", base_api_path, query_parameters.join("&")));
}
self.links = links;
}
pub fn wrap(&mut self, item: D) {
self.data = item;
self.type_ = D::get_type();
self.set_links();
}
pub fn wrap_new(item: D, parent: &ApiPage<D>) -> ApiItem<D> {
let mut return_object = ApiItem {
base_url: parent.base_url.to_string(),
minimal_data: parent.minimal_data,
..Default::default()
};
return_object.wrap(item);
return_object
}
pub fn get_nested_items(&self) -> bool {
match self.minimal_data {
Some(true) => false,
Some(false) => true,
None => true,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Default, JsonSchema)]
#[schemars(example = "Self::example")]
pub struct ApiItemLinks {
#[serde(rename = "self")]
pub self_: Option<String>,
}
impl SchemaExample for ApiItemLinks {
fn example() -> Self {
Self {
self_: Some("http://127.0.0.1:20350/api/examples/5".to_owned()),
}
}
}