use crate::{Item, Result};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use stac::{Link, Links};
const ITEM_COLLECTION_TYPE: &str = "FeatureCollection";
#[derive(Debug, Serialize, Deserialize)]
pub struct ItemCollection {
#[serde(
deserialize_with = "deserialize_type",
serialize_with = "serialize_type"
)]
r#type: String,
#[serde(rename = "features")]
pub items: Vec<Item>,
pub links: Vec<Link>,
#[serde(skip_serializing_if = "Option::is_none", rename = "numberMatched")]
pub number_matched: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "numberReturned")]
pub number_returned: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<Context>,
#[serde(flatten)]
pub additional_fields: Map<String, Value>,
#[serde(skip)]
pub next: Option<Map<String, Value>>,
#[serde(skip)]
pub prev: Option<Map<String, Value>>,
#[serde(skip)]
pub first: Option<Map<String, Value>>,
#[serde(skip)]
pub last: Option<Map<String, Value>>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Context {
pub returned: u64,
pub limit: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub matched: Option<u64>,
#[serde(flatten)]
pub additional_fields: Map<String, Value>,
}
impl ItemCollection {
pub fn new(items: Vec<Item>) -> Result<ItemCollection> {
let number_returned = items.len();
Ok(ItemCollection {
r#type: ITEM_COLLECTION_TYPE.to_string(),
items,
links: Vec::new(),
number_matched: None,
number_returned: Some(number_returned.try_into()?),
context: None,
additional_fields: Map::new(),
next: None,
prev: None,
first: None,
last: None,
})
}
}
impl Links for ItemCollection {
fn links(&self) -> &[Link] {
&self.links
}
fn links_mut(&mut self) -> &mut Vec<Link> {
&mut self.links
}
}
impl Default for ItemCollection {
fn default() -> Self {
ItemCollection {
r#type: "FeatureCollection".to_string(),
items: Vec::new(),
links: Vec::new(),
number_matched: None,
number_returned: None,
context: None,
additional_fields: Map::default(),
next: None,
prev: None,
first: None,
last: None,
}
}
}
impl From<Vec<Item>> for ItemCollection {
fn from(items: Vec<Item>) -> Self {
ItemCollection {
items,
..Default::default()
}
}
}
fn deserialize_type<'de, D>(deserializer: D) -> std::result::Result<String, D::Error>
where
D: serde::de::Deserializer<'de>,
{
stac::deserialize_type(deserializer, ITEM_COLLECTION_TYPE)
}
fn serialize_type<S>(r#type: &String, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
stac::serialize_type(r#type, serializer, ITEM_COLLECTION_TYPE)
}