Files
alkstore/alkstore-contract-suite/src/factory.rs
T

45 lines
2.1 KiB
Rust

//! The factory abstraction the suite is parameterized over (ADR-022).
//!
//! One shape, deliberately minimal: produce a fresh store over an
//! isolated backing store, plus teardown. Engines implement this in
//! their dev-dependency wiring — a fresh file (SQLite) or fresh schema
//! (Postgres) per call, so properties never observe one another's
//! rows.
//!
//! The factory shape may evolve as engines adopt the suite (wave 3/4
//! feedback) — ADR-022 records the *layout* decision, not a frozen
//! API. Changes here are test-side non-events (ADR-017 §2 class 4:
//! the suite tests the contract, it is not contract surface).
use alkstore::{BoxedFuture, Result, Store};
/// Produces fresh, isolated [`Store`]s for the suite's properties.
///
/// Implementers — engine crates, in their dev-dependency wiring —
/// yield a [`Box<dyn Store>`](Store) over an isolated backing store (a
/// fresh file or fresh schema per call, so a property's rows never
/// outlive its run into another's) plus a teardown disposing of the
/// backing store. Implementations must be `Send + Sync` so a factory
/// can be shared across property runs.
///
/// Rows call [`StoreFactory::open`], drive their assertions, and call
/// [`StoreFactory::teardown`] before returning; a rollback-less early
/// exit (a failing assertion panics the row) is the caller's harness
/// concern, which is why teardown is also required to be safe to run
/// against an abandoned store (drop, close, delete).
///
/// The async surface rides the same boxed-future posture as the
/// contract traits (`BoxedFuture`), so implementers need no macros.
pub trait StoreFactory: Send + Sync {
/// Open a fresh store over an isolated backing store.
fn open(&self) -> BoxedFuture<'_, Result<Box<dyn Store>>>;
/// Tear down the backing store behind this factory instance.
///
/// Idempotent per instance. The engine owns what teardown means —
/// deleting a temp file, dropping a schema, closing a pool — and
/// owns the isolated-ness guarantee (no two `open` calls share
/// rows).
fn teardown(&self) -> BoxedFuture<'_, Result<()>>;
}