use super::{ItemCollection, Items, Search};
use crate::{Collection, Error, Item};
use std::future::Future;
pub trait SearchClient: Send + Sync {
type Error: Send;
fn search(
&self,
search: Search,
) -> impl Future<Output = Result<ItemCollection, Self::Error>> + Send;
fn item(
&self,
collection_id: &str,
item_id: &str,
) -> impl Future<Output = Result<Option<Item>, Self::Error>> + Send
where
Self::Error: From<Error>,
{
async move {
let search = Search::default()
.ids(vec![item_id.to_string()])
.collections(vec![collection_id.to_string()]);
let mut item_collection = self.search(search).await?;
if item_collection.items.len() == 1 {
let api_item = item_collection.items.pop().expect("just checked length");
let item: Item = serde_json::from_value(serde_json::Value::Object(api_item))
.map_err(Error::from)?;
Ok(Some(item))
} else {
Ok(None)
}
}
}
fn items(
&self,
collection_id: &str,
items: Items,
) -> impl Future<Output = Result<ItemCollection, Self::Error>> + Send {
async move {
let search = items.search_collection(collection_id);
self.search(search).await
}
}
}
pub trait CollectionSearchClient: Send + Sync {
type Error: Send;
fn collections(&self) -> impl Future<Output = Result<Vec<Collection>, Self::Error>> + Send;
fn collection(
&self,
id: &str,
) -> impl Future<Output = Result<Option<Collection>, Self::Error>> + Send {
async move {
let collections = self.collections().await?;
Ok(collections.into_iter().find(|c| c.id == id))
}
}
}
pub trait TransactionClient: Send {
type Error: Send;
fn add_collection(
&mut self,
collection: Collection,
) -> impl Future<Output = Result<(), Self::Error>> + Send;
fn add_item(&mut self, item: Item) -> impl Future<Output = Result<(), Self::Error>> + Send;
fn add_items(
&mut self,
items: Vec<Item>,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
async move {
for item in items {
self.add_item(item).await?;
}
Ok(())
}
}
}
#[cfg(feature = "geoarrow")]
pub trait ArrowSearchClient {
type Error;
type RecordBatchStream<'a>: arrow_array::RecordBatchReader
where
Self: 'a;
fn search_to_arrow(&self, search: Search) -> Result<Self::RecordBatchStream<'_>, Self::Error>;
}