1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use crate::{Item, Result};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use stac::{Link, Links};
const ITEM_COLLECTION_TYPE: &str = "FeatureCollection";
/// The return value of the `/items` and `/search` endpoints.
///
/// This might be a [stac::ItemCollection], but if the [fields
/// extension](https://github.com/stac-api-extensions/fields) is used, it might
/// not be. Defined by the [itemcollection
/// fragment](https://github.com/radiantearth/stac-api-spec/blob/main/fragments/itemcollection/README.md).
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ItemCollection {
/// Always "FeatureCollection" to provide compatibility with GeoJSON.
pub r#type: String,
/// A possibly-empty array of Item objects.
#[serde(rename = "features")]
pub items: Vec<Item>,
/// An array of Links related to this ItemCollection.
pub links: Vec<Link>,
/// The number of Items that meet the selection parameters, possibly estimated.
#[serde(skip_serializing_if = "Option::is_none", rename = "numberMatched")]
pub number_matched: Option<u64>,
/// The number of Items in the features array.
#[serde(skip_serializing_if = "Option::is_none", rename = "numberReturned")]
pub number_returned: Option<u64>,
/// The search-related metadata for the [ItemCollection].
///
/// Part of the [context extension](https://github.com/stac-api-extensions/context).
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<Context>,
/// Additional fields.
#[serde(flatten)]
pub additional_fields: Map<String, Value>,
}
/// The search-related metadata for the [ItemCollection].
///
/// Part of the [context extension](https://github.com/stac-api-extensions/context).
#[derive(Debug, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Context {
/// The count of results returned by this response. Equal to the cardinality
/// of features array.
pub returned: u64,
/// The maximum number of results to which the result was limited.
pub limit: Option<u64>,
/// The count of total number of results that match for this query, possibly
/// estimated, particularly in the context of NoSQL data stores.
#[serde(skip_serializing_if = "Option::is_none")]
pub matched: Option<u64>,
/// Additional fields.
#[serde(flatten)]
pub additional_fields: Map<String, Value>,
}
impl ItemCollection {
/// Creates a new [ItemCollection] from a vector of items.
///
/// # Examples
///
/// ```
/// let item: stac_api::Item = stac::Item::new("an-id").try_into().unwrap();
/// let item_collection = stac_api::ItemCollection::new(vec![item]).unwrap();
/// ```
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(),
})
}
}
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(),
}
}
}