Trait RowStream
pub trait RowStream {
type Row<'a>: RowRef
where Self: 'a;
// Required method
fn next_row(&mut self) -> Option<Self::Row<'_>>;
}Expand description
A lending stream of rows. next_row reborrows self, so the row it
returns is invalidated by the next call — exactly the SQLite cursor
contract, now a compile-time invariant. This is the leaf source’s output
shape; it is not std::iter::Iterator (which hands out owned items and
cannot express the borrow). GAT-based lending, stable since Rust 1.65.
The lending contract is enforced by the borrow checker. Holding a row
(or a borrowed Value out of it) across the next next_row is a compile
error — for SQLite that is precisely “use after sqlite3_step,” caught at
compile time instead of corrupting a read. The same invariant holds for the
memory backend (the row borrows the cursor’s Rc snapshot), so this fails to
compile against either leaf:
use rindle_value::value::{owned_row, OwnedRow, OwnedValue, RowRef, RowStream};
struct Rows<'r>(std::slice::Iter<'r, OwnedRow>);
impl<'r> RowStream for Rows<'r> {
type Row<'a> = &'a OwnedRow where Self: 'a;
fn next_row(&mut self) -> Option<Self::Row<'_>> { self.0.next() }
}
let rows = vec![owned_row(vec![OwnedValue::Int(1)]), owned_row(vec![OwnedValue::Int(2)])];
let mut c = Rows(rows.iter());
let r1 = c.next_row().unwrap(); // borrows `c`
let r2 = c.next_row().unwrap(); // ERROR: second &mut borrow of `c` while r1 lives
let _ = (r1.col(0), r2.col(0)); // r1 still used here ⇒ borrows overlapTo keep a row past the step, own it — RowRef::to_owned_row (a copy on the
SQLite leaf, an Arc bump on the memory leaf):
use rindle_value::value::{owned_row, OwnedRow, OwnedValue, RowRef, RowStream, Value};
// The engine's B+tree cursor is the real implementor; any stepping shape works.
struct Rows<'r>(std::slice::Iter<'r, OwnedRow>);
impl<'r> RowStream for Rows<'r> {
type Row<'a> = &'a OwnedRow where Self: 'a;
fn next_row(&mut self) -> Option<Self::Row<'_>> { self.0.next() }
}
let rows = vec![owned_row(vec![OwnedValue::Int(1)])];
let mut c = Rows(rows.iter());
let owned = c.next_row().unwrap().to_owned_row(); // escapes the step
assert!(matches!(owned.col(0), Value::Int(1)));Required Associated Types§
Required Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.