pub struct TimelineCursor { /* private fields */ }Expand description
The scrub position over a validated LoadedBundle: the current integer
step plus one per-table index for “as of position” slicing
(docs/01-domain-model.md §10).
The cursor is Copy and holds only indices — it never borrows or copies
a table, so it is cheap to snapshot (the incremental_equals_arbitrary
property compares two cursors by value). Every query takes the same
LoadedBundle it was constructed from and returns borrowed rows; passing a
different bundle yields meaningless indices (a caller contract, not
re-validated).
position and end_step are read-only
ACCESSORS (a screen renders “step position of end_step”); the fields are
private so the cursor can only move through seek, which
re-establishes the index invariant — a desynced direct write is
unrepresentable.
Implementations§
Source§impl TimelineCursor
impl TimelineCursor
Sourcepub fn new(bundle: &LoadedBundle) -> Self
pub fn new(bundle: &LoadedBundle) -> Self
Build a cursor over bundle at position = 0 with each index resolved by
binary search (docs/01-domain-model.md §10).
end_step is N - 1 for an N-step run and 0 for an
empty run — relying on the #32 guarantee that equity_curve is one row per
step over the contiguous domain 0..N (module docs, reliance 1).
Sourcepub const fn is_at_start(self) -> bool
pub const fn is_at_start(self) -> bool
Whether the cursor is at the first step (position == 0).
Sourcepub const fn is_at_end(self) -> bool
pub const fn is_at_end(self) -> bool
Whether the cursor is at the last step (position == end_step) — the point
at which playback stops.
Sourcepub fn seek(&mut self, to: SeekTo, bundle: &LoadedBundle)
pub fn seek(&mut self, to: SeekTo, bundle: &LoadedBundle)
Move the cursor by to, re-establishing every per-table index for the new
clamped position (docs/04-replay-mode.md §4).
SeekTo::StepBywalks each index incrementally from its current value (O(rows moved), never a rescan) — the O(1) play-head /←/→path;SeekTo::Stepresolves each index by binary search (O(log n)) — theHome/End/large-jump path.
The target position is clamped to 0..=end_step with checked arithmetic,
so a step past either edge (including a playback tick at the end) is a no-op
clamp, never an overflow or a wrap. Both paths land on the same index
invariant, so the result depends only on the final position.
Sourcepub fn advance_playback(&mut self, playback: Playback, bundle: &LoadedBundle)
pub fn advance_playback(&mut self, playback: Playback, bundle: &LoadedBundle)
Apply one scheduled playback advance: seek forward by playback’s
quantum (Playback::tick_seek), or leave the cursor unchanged when paused
(docs/04-replay-mode.md §4). The forward step is a SeekTo::StepBy, so
the seek clamps at end_step — playback stops at the end
of the tape and never wraps. This is the model of the quantum and the
stop-at-end rule; the tick cadence that calls it is the app’s (issue #34).
Sourcepub fn visible_equity<'b>(&self, bundle: &'b LoadedBundle) -> &'b [EquityPoint]
pub fn visible_equity<'b>(&self, bundle: &'b LoadedBundle) -> &'b [EquityPoint]
The equity curve up to and including the head step — the drawdown-shaded
series the equity screen renders (docs/04-replay-mode.md §4).
Sourcepub fn visible_greeks<'b>(
&self,
bundle: &'b LoadedBundle,
) -> &'b [GreeksAttribution]
pub fn visible_greeks<'b>( &self, bundle: &'b LoadedBundle, ) -> &'b [GreeksAttribution]
The per-step P&L attribution rows with step <= position — the as-of
attribution slice up to and including the head step
(docs/04-replay-mode.md §4). ChainView never recomputes or sums the
decomposition: the replay screen renders the head-step row
(head_greeks) as authored, so this full slice is
currently unused by the screen — it is retained for the deferred
attribution-history / #49 payoff work.
Sourcepub fn visible_fills<'b>(&self, bundle: &'b LoadedBundle) -> &'b [Fill]
pub fn visible_fills<'b>(&self, bundle: &'b LoadedBundle) -> &'b [Fill]
Every fill with step <= position — the drill-down history up to the head.
Sourcepub fn visible_positions<'b>(
&self,
bundle: &'b LoadedBundle,
) -> &'b [PositionRow]
pub fn visible_positions<'b>( &self, bundle: &'b LoadedBundle, ) -> &'b [PositionRow]
Every positions row with step <= position, terminal rows included — the
raw as-of window. open_positions is the filtered,
post-fill open set most callers want.
Sourcepub fn head_equity<'b>(
&self,
bundle: &'b LoadedBundle,
) -> Option<&'b EquityPoint>
pub fn head_equity<'b>( &self, bundle: &'b LoadedBundle, ) -> Option<&'b EquityPoint>
The equity_curve row at the head step (step == position), or None for
an empty run. Relies on reliance 1: the last visible equity row is the
head-step row.
Sourcepub fn head_greeks<'b>(
&self,
bundle: &'b LoadedBundle,
) -> Option<&'b GreeksAttribution>
pub fn head_greeks<'b>( &self, bundle: &'b LoadedBundle, ) -> Option<&'b GreeksAttribution>
The greeks_attribution row at the head step (step == position), or
None for an empty run. Relies on reliance 1.
Sourcepub fn head_fills<'b>(&self, bundle: &'b LoadedBundle) -> &'b [Fill]
pub fn head_fills<'b>(&self, bundle: &'b LoadedBundle) -> &'b [Fill]
The fill(s) at exactly the head step (step == position) — the rows a
drill-down highlights under the scrub head. Empty when no fill landed on the
head step. A realistic order that walked several price levels appears as
several rows here.
Sourcepub fn open_positions<'b>(
&self,
bundle: &'b LoadedBundle,
) -> Vec<&'b PositionRow>
pub fn open_positions<'b>( &self, bundle: &'b LoadedBundle, ) -> Vec<&'b PositionRow>
The post-fill open-position set at the head step
(docs/04-replay-mode.md §4): the latest non-terminal positions row per
position_id with step <= position, excluding any position_id whose
terminal (exit_reason-bearing) row is at step <= position.
A leg closed at or before the cursor is not shown open; an opening and a
closing row at the same step resolve deterministically (the terminal row
wins the exclusion); a leg with open_at_end = true and no terminal row
stays open through end_step. This is the single algorithm the drill-down
and the deferred payoff (#49) both read, so the two screens can never
disagree.
The result is ordered by position_id (deterministic) and borrows into the
bundle. It is O(k log k) in the k visible position rows, not on the draw
path — call it on a seek, not per frame. Relies on reliance 4 (stable
position_id, positive quantity).
Trait Implementations§
Source§impl Clone for TimelineCursor
impl Clone for TimelineCursor
Source§fn clone(&self) -> TimelineCursor
fn clone(&self) -> TimelineCursor
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for TimelineCursor
Source§impl Debug for TimelineCursor
impl Debug for TimelineCursor
impl Eq for TimelineCursor
Source§impl PartialEq for TimelineCursor
impl PartialEq for TimelineCursor
impl StructuralPartialEq for TimelineCursor
Auto Trait Implementations§
impl Freeze for TimelineCursor
impl RefUnwindSafe for TimelineCursor
impl Send for TimelineCursor
impl Sync for TimelineCursor
impl Unpin for TimelineCursor
impl UnsafeUnpin for TimelineCursor
impl UnwindSafe for TimelineCursor
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.