Skip to main content

miniextendr_api/altrep_data/
iter.rs

1//! Iterator-backed ALTREP data adaptors.
2//!
3//! Provides lazy backing data for ALTREP vectors from Rust iterators. Elements
4//! are generated on-demand and cached for repeat access.
5//!
6//! ## Data adaptors, not R-facing vectors
7//!
8//! The `*Data` types in these submodules implement only the data-level traits
9//! ([`AltrepLen`](crate::altrep_data::AltrepLen) + the matching `Alt*Data`
10//! trait). They do **not** implement
11//! [`RegisterAltrep`](crate::altrep::RegisterAltrep), so they cannot back a
12//! live R SEXP by themselves. To expose one to R, wrap it in a concrete
13//! struct deriving the matching `Altrep*` derive with `#[altrep(manual)]` and
14//! delegate the data-trait methods to the inner adaptor (the derive cannot be
15//! applied to the adaptors directly because they are generic over the
16//! iterator type):
17//!
18//! ```ignore
19//! use miniextendr_api::altrep_data::{AltIntegerData, AltrepLen, IterIntData};
20//!
21//! #[derive(miniextendr_api::AltrepInteger)]
22//! #[altrep(class = "MyLazyInts", manual)]
23//! struct MyLazyInts {
24//!     inner: IterIntData<std::ops::Range<i32>>,
25//! }
26//!
27//! impl AltrepLen for MyLazyInts {
28//!     fn altrep_len(&self) -> usize {
29//!         self.inner.altrep_len()
30//!     }
31//! }
32//!
33//! impl AltIntegerData for MyLazyInts {
34//!     fn elt(&self, i: usize) -> i32 {
35//!         self.inner.elt(i)
36//!     }
37//! }
38//! ```
39//!
40//! ## Duplication and serialization
41//!
42//! The standard atomic and string adapters implement `Clone` when their
43//! concrete iterator does. Cloning preserves the cached prefix and remaining
44//! iterator without advancing it. They also implement `AltrepSerialize`:
45//! saving realizes the declared finite sequence; restoring uses a complete
46//! cache and never needs to construct `I`. Delegate that trait from a concrete
47//! registered class and select `#[altrep(manual, serialize, duplicate = "clone")]`.
48//! The bridge preserves authoritative R writes in data2 as well as that cache.
49//! The list adapter keeps its cache in one R list that it roots itself,
50//! storing each yielded value before requesting another. Its clone copies that
51//! list and its remaining iterator; serialization saves the realized list.
52//! These operations, including dropping the adapter, belong on R's main thread.
53//!
54//! ## Submodules
55//!
56//! - [`state`]: Core `IterState<I, T>` + standard data adaptors (Int, Real, Logical, Raw)
57//! - [`coerce`]: Coerced variants (`IterIntCoerceData`, `IterRealCoerceData`, `IterIntFromBoolData`)
58//!   plus the String/Complex data adaptors (`IterStringData`, `IterComplexData`)
59//! - [`list`]: GC-rooted `IterListData` for iterators yielding R objects
60//! - [`sparse`]: Sparse iterators using `nth()` for skip-ahead (`SparseIterState`)
61//! - [`windowed`]: Sliding-window iterators (`WindowedIterState`)
62
63mod coerce;
64mod extension;
65mod list;
66mod macros;
67mod sparse;
68mod state;
69mod windowed;
70
71pub use coerce::*;
72pub use extension::*;
73pub use list::*;
74pub use sparse::*;
75pub use state::*;
76pub use windowed::*;