Rindle docs and package mapSkip to main content

RowStream

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 overlap

To 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§

type Row<'a>: RowRef where Self: 'a

Required Methods§

fn next_row(&mut self) -> Option<Self::Row<'_>>

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.

Implementors§