use crate::{Error, Fields, Filter, GetItems, Items, Result, Sortby};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use stac::Geometry;
use std::collections::HashMap;
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Search {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bbox: Option<Vec<f64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub datetime: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub intersects: Option<Geometry>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ids: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collections: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fields: Option<Fields>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sortby: Option<Vec<Sortby>>,
#[serde(skip_serializing_if = "Option::is_none", rename = "filter-crs")]
pub filter_crs: Option<String>,
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub filter: Option<Filter>,
#[serde(skip_serializing_if = "Option::is_none")]
pub query: Option<Map<String, Value>>,
#[serde(flatten)]
pub additional_fields: Map<String, Value>,
}
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct GetSearch {
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<String>,
pub bbox: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub datetime: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub intersects: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ids: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub collections: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fields: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sortby: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", rename = "filter-crs")]
pub filter_crs: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_lang: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter: Option<String>,
#[serde(flatten)]
pub additional_fields: HashMap<String, String>,
}
impl TryFrom<Search> for GetSearch {
type Error = Error;
fn try_from(search: Search) -> Result<GetSearch> {
let items = Items {
limit: search.limit,
bbox: search.bbox,
datetime: search.datetime,
fields: search.fields,
sortby: search.sortby,
filter_crs: search.filter_crs,
filter: search.filter,
query: search.query,
additional_fields: search.additional_fields,
};
let get_items: GetItems = items.try_into()?;
let intersects = search
.intersects
.map(|intersects| serde_json::to_string(&intersects))
.transpose()?;
Ok(GetSearch {
limit: get_items.limit,
bbox: get_items.bbox,
datetime: get_items.datetime,
intersects: intersects,
ids: search.ids,
collections: search.collections,
fields: get_items.fields,
sortby: get_items.sortby,
filter_crs: get_items.filter_crs,
filter_lang: get_items.filter_lang,
filter: get_items.filter,
additional_fields: get_items.additional_fields,
})
}
}
impl TryFrom<GetSearch> for Search {
type Error = Error;
fn try_from(get_search: GetSearch) -> Result<Search> {
let get_items = GetItems {
limit: get_search.limit,
bbox: get_search.bbox,
datetime: get_search.datetime,
fields: get_search.fields,
sortby: get_search.sortby,
filter_crs: get_search.filter_crs,
filter: get_search.filter,
filter_lang: get_search.filter_lang,
additional_fields: get_search.additional_fields,
};
let items: Items = get_items.try_into()?;
let intersects = get_search
.intersects
.map(|intersects| serde_json::from_str(&intersects))
.transpose()?;
Ok(Search {
limit: items.limit,
bbox: items.bbox,
datetime: items.datetime,
intersects: intersects,
ids: get_search.ids,
collections: get_search.collections,
fields: items.fields,
sortby: items.sortby,
filter_crs: items.filter_crs,
filter: items.filter,
query: items.query,
additional_fields: items.additional_fields,
})
}
}