use ciborium::Value as CborValue;
use vantage_core::Result;
use vantage_types::Record;
use super::Vista;
use crate::{
capabilities::Capability,
change::{VistaChange, VistaChangeStream},
computed,
page::Page,
};
impl Vista {
pub async fn count(&self) -> Result<i64> {
self.shell().count().await
}
pub async fn fetch_window(&self, offset: usize, limit: usize) -> Result<Page> {
if offset > 0 {
self.require(Capability::Window)?;
}
let mut page = self.shell().fetch_window(offset, limit).await?;
self.fill_computed_rows(page.rows.iter_mut().map(|(_, r)| r))?;
Ok(page)
}
pub async fn fetch_cursor(
&self,
token: Option<CborValue>,
limit: usize,
) -> Result<(Page, Option<CborValue>)> {
self.require(Capability::Cursor)?;
let (mut page, next) = self.shell().fetch_cursor(token, limit).await?;
self.fill_computed_rows(page.rows.iter_mut().map(|(_, r)| r))?;
Ok((page, next))
}
pub async fn watch(&self) -> Result<VistaChangeStream> {
self.require(Capability::Subscribe)?;
let mut changes = self.shell().watch().await?;
let columns = self.computed_columns();
if columns.is_empty() {
return Ok(changes);
}
Ok(Box::pin(async_stream::stream! {
while let Some(change) =
std::future::poll_fn(|cx| changes.as_mut().poll_next(cx)).await
{
yield change.and_then(|change| match change {
VistaChange::Inserted { id, mut value } => {
computed::fill(&columns, &mut value)?;
Ok(VistaChange::Inserted { id, value })
}
VistaChange::Updated { id, mut value } => {
computed::fill(&columns, &mut value)?;
Ok(VistaChange::Updated { id, value })
}
other => Ok(other),
});
}
}))
}
pub fn get_ref(&self, relation: &str, row: Option<&Record<CborValue>>) -> Result<Vista> {
self.shell().get_ref(relation, row)
}
pub async fn import_values(
&self,
rows: &indexmap::IndexMap<String, Record<CborValue>>,
) -> Result<usize> {
self.require_write(Capability::Import, "import")?;
let rows = self.without_computed_all(rows);
self.shell().import(&rows).await
}
}