use std::sync::Arc;
use std::time::Duration;
use ciborium::Value as CborValue;
use tempfile::TempDir;
use vantage_core::Result;
use vantage_dataset::prelude::{ReadableValueSet, WritableValueSet};
use vantage_diorama::{FlashKind, Lens};
use vantage_types::Record;
use vantage_vista::{Column, Vista, VistaMetadata, mocks::MockShell};
fn master() -> Vista {
let metadata = VistaMetadata::new()
.with_column(Column::new("id", "String").with_flag("id"))
.with_column(Column::new("name", "String"))
.with_id_column("id");
Vista::new("tasks", Box::new(MockShell::new().with_metadata(metadata)))
}
fn record(name: &str) -> Record<CborValue> {
let mut r = Record::new();
r.insert("name".to_string(), CborValue::Text(name.to_string()));
r
}
#[tokio::main]
async fn main() -> Result<()> {
let tmp = TempDir::new().expect("tempdir");
let lens = Arc::new(
Lens::new()
.cache_at(tmp.path().join("cache.redb"))
.on_flash(|dio, flash| {
let dio = dio.clone();
async move {
let label = flash.id().unwrap_or("*");
println!("on_flash: {:?} {label} → master + cache", flash.kind());
match flash.kind() {
FlashKind::Insert => {
let id = flash.id().expect("insert has id").to_string();
dio.master().insert_value(id.clone(), flash.patch()).await?;
dio.cache().insert_value(&id, flash.patch()).await?;
}
FlashKind::Replace => {
let id = flash.id().expect("replace has id").to_string();
dio.master()
.replace_value(id.clone(), flash.patch())
.await?;
dio.cache().insert_value(&id, flash.patch()).await?;
}
FlashKind::Patch => {
let id = flash.id().expect("patch has id").to_string();
dio.master().patch_value(id.clone(), flash.patch()).await?;
let merged = flash.after().expect("patch has an after");
dio.cache().insert_value(&id, &merged).await?;
}
FlashKind::Delete => {
let id = flash.id().expect("delete has id").to_string();
dio.master().delete(id.clone()).await?;
dio.cache().delete_value(&id).await?;
}
FlashKind::Clear => {
dio.master().delete_all().await?;
dio.cache().clear().await?;
}
}
Ok(())
}
})
.build()
.expect("build lens"),
);
let dio = lens.make_dio(master()).await?;
let facade = dio.vista();
facade.insert_value("t1", &record("write docs")).await?;
facade.insert_value("t2", &record("ship stage 3")).await?;
tokio::time::sleep(Duration::from_millis(50)).await;
println!("\ncache reads after writes drained:");
for (id, row) in facade.list_values().await? {
let name = row.get("name").and_then(|v| match v {
CborValue::Text(s) => Some(s.as_str()),
_ => None,
});
println!(" {id}: {}", name.unwrap_or(""));
}
Ok(())
}