use std::path::Path;
use crate::{
geoparquet::{FromGeoparquet, IntoGeoparquet},
json::{FromJson, ToJson},
ndjson::{FromNdjson, ToNdjson},
Format, Href, Result,
};
pub fn read<T: Href + FromJson + FromNdjson + FromGeoparquet>(href: impl ToString) -> Result<T> {
let href = href.to_string();
let format = Format::infer_from_href(&href).unwrap_or_default();
format.read(href)
}
#[cfg(feature = "object-store")]
pub async fn get<T: Href + FromJson + FromNdjson + FromGeoparquet>(
href: impl ToString,
) -> Result<T> {
let options: [(&str, &str); 0] = [];
get_opts(href, options).await
}
#[cfg(feature = "object-store")]
pub async fn get_opts<T, I, K, V>(href: impl ToString, options: I) -> Result<T>
where
T: Href + FromJson + FromNdjson + FromGeoparquet,
I: IntoIterator<Item = (K, V)>,
K: AsRef<str>,
V: Into<String>,
{
let href = href.to_string();
let format = Format::infer_from_href(&href).unwrap_or_default();
format.get_opts(href, options).await
}
pub fn write<T: ToJson + ToNdjson + IntoGeoparquet>(
path: impl AsRef<Path>,
value: T,
) -> Result<()> {
let path = path.as_ref();
let format = path
.to_str()
.and_then(Format::infer_from_href)
.unwrap_or_default();
format.write(path, value)
}
#[cfg(feature = "object-store")]
pub async fn put<T>(href: impl ToString, value: T) -> Result<Option<object_store::PutResult>>
where
T: ToJson + ToNdjson + IntoGeoparquet,
{
let options: [(&str, &str); 0] = [];
put_opts(href, value, options).await
}
#[cfg(feature = "object-store")]
pub async fn put_opts<T, I, K, V>(
href: impl ToString,
value: T,
options: I,
) -> Result<Option<object_store::PutResult>>
where
T: ToJson + ToNdjson + IntoGeoparquet,
I: IntoIterator<Item = (K, V)>,
K: AsRef<str>,
V: Into<String>,
{
let href = href.to_string();
let format = Format::infer_from_href(&href).unwrap_or_default();
format.put_opts(href, value, options).await
}
#[cfg(test)]
mod tests {
use tempdir::TempDir;
use crate::{Catalog, Collection, Item, ItemCollection};
macro_rules! read {
($function:ident, $filename:expr, $value:ty $(, $meta:meta)?) => {
#[test]
$(#[$meta])?
fn $function() {
use crate::Href;
let value: $value = crate::read($filename).unwrap();
assert!(value.href().is_some());
}
};
}
read!(read_item_from_path, "examples/simple-item.json", Item);
read!(read_catalog_from_path, "examples/catalog.json", Catalog);
read!(
read_collection_from_path,
"examples/collection.json",
Collection
);
read!(
read_item_collection_from_path,
"data/item-collection.json",
ItemCollection
);
#[cfg(feature = "reqwest")]
mod read_with_reqwest {
use crate::{Catalog, Collection, Item};
read!(
read_item_from_url,
"https://raw.githubusercontent.com/radiantearth/stac-spec/master/examples/simple-item.json",
Item
);
read!(
read_catalog_from_url,
"https://raw.githubusercontent.com/radiantearth/stac-spec/master/examples/catalog.json",
Catalog
);
read!(
read_collection_from_url,
"https://raw.githubusercontent.com/radiantearth/stac-spec/master/examples/collection.json",
Collection
);
}
#[test]
#[cfg(not(feature = "reqwest"))]
fn read_without_reqwest() {
assert!(matches!(
super::read::<Item>("http://stac-rs.test/item.json").unwrap_err(),
crate::Error::FeatureNotEnabled("reqwest")
));
}
#[test]
#[cfg(feature = "geoparquet")]
fn read_geoparquet() {
let _: ItemCollection = super::read("data/extended-item.parquet").unwrap();
}
#[test]
#[cfg(not(feature = "geoparquet"))]
fn read_geoparquet_without_geoparquet() {
let _ = super::read::<ItemCollection>("data/extended-item.parquet").unwrap_err();
}
#[tokio::test]
#[cfg(all(feature = "object-store", not(target_os = "windows")))]
async fn get() {
let path = format!(
"file://{}",
std::fs::canonicalize("examples/simple-item.json")
.unwrap()
.to_string_lossy()
);
let _: Item = super::get(path).await.unwrap();
}
#[test]
fn write() {
let tempdir = TempDir::new("write").unwrap();
let item = Item::new("an-id");
super::write(tempdir.path().join("item.json"), item).unwrap();
let item: Item = super::read(tempdir.path().join("item.json").to_string_lossy()).unwrap();
assert_eq!(item.id, "an-id");
}
#[tokio::test]
#[cfg(feature = "object-store")]
async fn put() {
let tempdir = TempDir::new("put").unwrap();
let path = format!(
"file://{}",
tempdir.path().join("item.json").to_string_lossy()
);
let item = Item::new("an-id");
assert!(super::put(path, item).await.unwrap().is_some());
let item: Item = crate::read(tempdir.path().join("item.json").to_string_lossy()).unwrap();
assert_eq!(item.id, "an-id");
}
}