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
//! Rust implementation of the STAC API specification.
//!
//! This crate **is**:
//!
//! - Data structures
//! - Link building
//!
//! This crate **is not**:
//!
//! - A server implementation
//!
//! For a STAC API server written in Rust, based on this crate, see
//! [stac-server-rs](http://github.com/gadomski/stac-server-rs).
//!
//! # Data structures
//!
//! Each API endpoint has its own data structure. In some cases, these are
//! light wrappers around [stac] data structures. In other cases, they can be
//! different -- e.g. the `/search` endpoint may not return [Items](stac::Item)
//! if the [fields](https://github.com/stac-api-extensions/fields) extension is
//! used, so the return type is a crate-specific [Item] struct.
//!
//! For example, here's the root structure (a.k.a the landing page):
//!
//! ```
//! use stac::Catalog;
//! use stac_api::Root;
//! let root = Root {
//! catalog: Catalog::new("an-id", "a description"),
//! conforms_to: vec!["https://api.stacspec.org/v1.0.0-rc.2/core".to_string()],
//! };
//! ```
//!
//! # Build links
//!
//! The [LinkBuilder] structure can build links to parts of a STAC API.
//! A [LinkBuilder] is created from a root href:
//!
//! ```
//! use stac_api::LinkBuilder;
//! let link_builder: LinkBuilder = "http://stac-api-rs.test/api/v1".parse().unwrap();
//! ```
//!
//! Link builders provide a variety of methods for building links to all parts of a STAC API:
//!
//! ```
//! # use stac_api::LinkBuilder;
//! # let link_builder: LinkBuilder = "http://stac-api-rs.test/api/v1".parse().unwrap();
//! let link = link_builder.items("a-collection-id", [("limit", "10")]).unwrap();
//! assert_eq!(link.href, "http://stac-api-rs.test/api/v1/collections/a-collection-id/items?limit=10");
//! ```
#![deny(missing_docs, unused_extern_crates)]
mod collections;
mod error;
mod fields;
mod item_collection;
mod link;
mod link_builder;
mod root;
mod search;
mod sort;
pub use {
collections::Collections,
error::Error,
fields::Fields,
item_collection::{Context, ItemCollection},
link::Link,
link_builder::LinkBuilder,
root::Root,
search::Search,
sort::Sortby,
};
/// Crate-specific result type.
pub type Result<T> = std::result::Result<T, Error>;
/// A crate-specific STAC Item struct.
///
/// By default, STAC API endpoints that return [stac::Item] objects return every
/// field of those Items. However, Item objects can have hundreds of fields, or
/// large geometries, and even smaller Item objects can add up when large
/// numbers of them are in results. Frequently, not all fields in an Item are
/// used, so this specification provides a mechanism for clients to request that
/// servers to explicitly include or exclude certain fields.
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Item(pub serde_json::Map<String, serde_json::Value>);
impl TryFrom<stac::Item> for Item {
type Error = serde_json::Error;
fn try_from(item: stac::Item) -> std::result::Result<Item, serde_json::Error> {
match serde_json::to_value(item)? {
serde_json::Value::Object(object) => Ok(Item(object)),
_ => panic!("a STAC item shouldn't be able to deserialize to anything but an object"),
}
}
}
impl TryFrom<Item> for stac::Item {
type Error = serde_json::Error;
fn try_from(item: Item) -> std::result::Result<stac::Item, serde_json::Error> {
serde_json::from_value(serde_json::Value::Object(item.0))
}
}