pub struct MailboxBuffers {Show 21 fields
pub agent_id: String,
pub inbox: Vec<MessageRow>,
pub sent: Vec<MessageRow>,
pub channel: Vec<MessageRow>,
pub wire: Vec<MessageRow>,
pub inbox_after: i64,
pub sent_after: i64,
pub channel_after: i64,
pub wire_after: i64,
pub inbox_cursor: CursorState,
pub sent_cursor: CursorState,
pub channel_cursor: CursorState,
pub wire_cursor: CursorState,
pub inbox_filter: String,
pub sent_filter: String,
pub channel_filter: String,
pub wire_filter: String,
pub inbox_search: String,
pub sent_search: String,
pub channel_search: String,
pub wire_search: String,
}Expand description
Per-agent buffer state — four tabs, four after_id cursors.
Lives on App so swapping the focused agent resets the cursors
without trying to back-fill: the operator sees only forward
motion in the tab they’re watching.
Fields§
§agent_id: StringThe focused agent’s id (<project>:<agent>), set by
refresh_mailbox. The sender != me source for the Inbox
merge’s inbound filter (#462) — kept here so rows() and the
cursor methods that read it don’t have to thread me through
every signature. Empty until the first refresh; an empty id
means the filter is a no-op (one transient frame at most).
inbox: Vec<MessageRow>§sent: Vec<MessageRow>§channel: Vec<MessageRow>§wire: Vec<MessageRow>§inbox_after: i64§sent_after: i64§channel_after: i64§wire_after: i64§inbox_cursor: CursorState§sent_cursor: CursorState§channel_cursor: CursorState§wire_cursor: CursorState§inbox_filter: String§sent_filter: String§channel_filter: String§wire_filter: String§inbox_search: String§sent_search: String§channel_search: String§wire_search: StringImplementations§
Source§impl MailboxBuffers
impl MailboxBuffers
Sourcepub fn rows(&self, tab: MailboxTab) -> Cow<'_, [MessageRow]>
pub fn rows(&self, tab: MailboxTab) -> Cow<'_, [MessageRow]>
Rows for tab, in ascending broker-id (receipt) order.
Most tabs hand back a borrow of their backing buffer. Inbox
is the exception (#462): it returns an owned, time-merged view
of inbound DMs + channel + wire, so it allocates. Cow lets the
common borrowed case stay zero-copy while the merged case owns
its Vec; callers use the result as a slice either way (Cow
derefs to [MessageRow]).
Sourcepub fn visible_indices(&self, tab: MailboxTab) -> Vec<usize>
pub fn visible_indices(&self, tab: MailboxTab) -> Vec<usize>
Indices into rows(tab) for the rows currently presented to
the operator — filter ∩ search. PR-2 swapped this body in;
every cursor method and the render call site stayed unchanged
from PR-1 because they go through this abstraction. A row at
rows(tab)[i] is visible iff:
filter_text(tab)is empty ORrow.sender(lower-cased) contains the filter (lower-cased) as a substring.search_text(tab)is empty ORrow.text(lower-cased) contains the search (lower-cased) as a substring.
When both axes are empty, the result is identity
(0..rows.len()) — PR-1’s default behavior recovers exactly.
Case-insensitive substring is the documented contract; the
per-keystroke recompute on small (~500-row) buffers is well
within budget.
Sourcepub fn visible_indices_in(
&self,
rows: &[MessageRow],
tab: MailboxTab,
) -> Vec<usize>
pub fn visible_indices_in( &self, rows: &[MessageRow], tab: MailboxTab, ) -> Vec<usize>
Like [visible_indices] but against an already-materialised row
slice. The render path already holds rows(tab), so it computes
visibility through this to avoid a second rows() call — for the
Inbox that call is non-trivial (it clones, sorts, and dedups the
merged feed, #462), and the per-frame render would otherwise pay
for the merge twice.
Sourcepub fn filter_text(&self, tab: MailboxTab) -> &str
pub fn filter_text(&self, tab: MailboxTab) -> &str
Current sender-substring filter on tab; empty = no filter.
Sourcepub fn search_text(&self, tab: MailboxTab) -> &str
pub fn search_text(&self, tab: MailboxTab) -> &str
Current body-substring search on tab; empty = no search.
Sourcepub fn input_push_char(
&mut self,
tab: MailboxTab,
kind: MailboxInputKind,
c: char,
)
pub fn input_push_char( &mut self, tab: MailboxTab, kind: MailboxInputKind, c: char, )
Push c onto the active input buffer for tab, then clamp
the cursor against the (possibly shorter) new visible_indices.
Called per-keystroke by the App input-mode handler.
Sourcepub fn input_pop_char(&mut self, tab: MailboxTab, kind: MailboxInputKind)
pub fn input_pop_char(&mut self, tab: MailboxTab, kind: MailboxInputKind)
Pop one character (Backspace) from the active input buffer for
tab, then re-clamp the cursor.
Sourcepub fn set_input(
&mut self,
tab: MailboxTab,
kind: MailboxInputKind,
value: String,
)
pub fn set_input( &mut self, tab: MailboxTab, kind: MailboxInputKind, value: String, )
Replace the active input buffer for tab wholesale — used by
the Esc-cancel-revert path to restore the pre-open snapshot.
pub fn cursor(&self, tab: MailboxTab) -> &CursorState
Sourcepub fn move_cursor_down(&mut self, tab: MailboxTab)
pub fn move_cursor_down(&mut self, tab: MailboxTab)
Move the cursor one row toward the tail; clamps at the last visible row (vim-like — no wrap).
Sourcepub fn move_cursor_up(&mut self, tab: MailboxTab)
pub fn move_cursor_up(&mut self, tab: MailboxTab)
Move the cursor one row toward the head; clamps at 0.
Sourcepub fn page_cursor_down(&mut self, tab: MailboxTab)
pub fn page_cursor_down(&mut self, tab: MailboxTab)
Jump a screen toward the tail.
Sourcepub fn page_cursor_up(&mut self, tab: MailboxTab)
pub fn page_cursor_up(&mut self, tab: MailboxTab)
Jump a screen toward the head.
Sourcepub fn cursor_home(&mut self, tab: MailboxTab)
pub fn cursor_home(&mut self, tab: MailboxTab)
Jump to the first visible row.
Sourcepub fn cursor_end(&mut self, tab: MailboxTab)
pub fn cursor_end(&mut self, tab: MailboxTab)
Jump to the last visible row.
Sourcepub fn inbox_at_tail(&self) -> bool
pub fn inbox_at_tail(&self) -> bool
Whether the Inbox cursor is at (or past) the tail of the merged
view — i.e. the operator is following new arrivals. Captured
before a refresh’s extends so [follow_inbox_tail] can re-anchor
the cursor afterwards: per-tab extend only follows the tab it
touches, but a channel/wire arrival grows the Inbox view too,
so without this the highlight would stop tracking the newest row
on the merged tab (#462).
Sourcepub fn follow_inbox_tail(&mut self)
pub fn follow_inbox_tail(&mut self)
Snap the Inbox cursor to the tail of the post-merge view. Called
after a refresh’s extends when [inbox_at_tail] held before
them, so following the Inbox keeps tracking the newest row even
when the new arrival came via the channel or wire buffer (#462).
Sourcepub fn extend(&mut self, tab: MailboxTab, batch: Vec<MessageRow>)
pub fn extend(&mut self, tab: MailboxTab, batch: Vec<MessageRow>)
Fold a freshly-fetched batch into the appropriate tab,
trimming to the last MAX_TAB_ROWS. Bumps the broker
pagination cursor to the last returned id when the batch is
non-empty. T-131 PR-1: when the UI cursor was already at the
tail (or the tab was empty), follow new arrivals — matching
the pre-T-131 “tail to whatever fits” UX. Always re-clamps the
UI cursor against the (possibly drained) post-extend visible
length so a stale index can never reference a missing row.
Trait Implementations§
Source§impl Clone for MailboxBuffers
impl Clone for MailboxBuffers
Source§fn clone(&self) -> MailboxBuffers
fn clone(&self) -> MailboxBuffers
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for MailboxBuffers
impl Debug for MailboxBuffers
Source§impl Default for MailboxBuffers
impl Default for MailboxBuffers
Source§fn default() -> MailboxBuffers
fn default() -> MailboxBuffers
Auto Trait Implementations§
impl Freeze for MailboxBuffers
impl RefUnwindSafe for MailboxBuffers
impl Send for MailboxBuffers
impl Sync for MailboxBuffers
impl Unpin for MailboxBuffers
impl UnsafeUnpin for MailboxBuffers
impl UnwindSafe for MailboxBuffers
Blanket Implementations§
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 more