pub struct CapturedSink { /* private fields */ }Expand description
Buffering sink that accumulates formatted entries for an
interactive consumer to drain. The TUI installs one for the
alt-screen lifetime so lsm_warn! / lsm_error! / lsm_debug!
surface in the live-preview warnings panel instead of painting
over the rendered frame.
Captured format is [<tag>] <msg> — the surrounding UI prefixes
each line with its own marker (e.g. ⚠), so the linesmith
prefix and colon would be redundant noise.
The buffer is bounded at CAPTURED_SINK_DEFAULT_CAP with
drop-oldest eviction and a counter exposed via Self::drain_detailed.
Today every emit happens during a synchronous render so drain
follows within microseconds; once v0.2 background plugins emit
between draws, the cap is what keeps a long-idle session from
accumulating megabytes of unread diagnostics. The Self::emit_seq
counter lets an idle event loop notice a new emission and trigger
a redraw without polling the mutex on every tick.
Implementations§
Source§impl CapturedSink
impl CapturedSink
Sourcepub fn with_capacity(cap: usize) -> Self
pub fn with_capacity(cap: usize) -> Self
Construct a sink with an explicit cap. A cap of zero is
clamped to one — a literal zero-cap would drop every emission,
leaving the consumer with nothing but a rising dropped counter.
Sourcepub fn drain(&self) -> Vec<String>
pub fn drain(&self) -> Vec<String>
Legacy text-only drain. Strips timestamps and dropped-count
metadata; used by callers (boot-failure stderr flush, the
_test_capture_warns helper) that only need the existing
[<tag>] <msg> strings. Resets the pending counter so an
event loop watching this sink stops requesting redraws.
Sourcepub fn drain_detailed(&self) -> CapturedDrain
pub fn drain_detailed(&self) -> CapturedDrain
Structured drain. Returns every buffered entry with its emission timestamp and the number of entries evicted by the cap since the previous drain. Resets both counters.
Counter resets happen while holding the entries mutex.
A concurrent emit serializes on the same lock, so its
increment is either fully observed by this drain (and
reflected in the returned counts) or strictly ordered
after the reset (and visible to the next drain) — never
silently clobbered.
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Current cap. Lock-free read so consumers that render the
drop-notice (“(N earlier entries dropped — cap M)”) pick up
the live value rather than baking in the Default constant.
Sourcepub fn emit_seq(&self) -> usize
pub fn emit_seq(&self) -> usize
Monotonic lifetime emission counter. The TUI event loop drives
a rising-edge wake by comparing this against a watermark of
max(pre_draw_emit_seq, last_drain_seq):
- Pre-draw snapshot keeps background emissions that arrive after the in-frame drain on the unseen side of the watermark — the next idle tick redraws them.
last_drain_seqlets in-frame emissions (the render itself emitting warnings while building the frame) advance the watermark — they were drained and shown to the user via the warnings panel, so they shouldn’t re-trigger a redraw.
Acquire-load pairs with the Release store in push so on
weakly-ordered architectures (ARM, RISC-V) the wake signal
doesn’t lag a poll tick.
Sourcepub fn last_drain_seq(&self) -> usize
pub fn last_drain_seq(&self) -> usize
emit_seq value at the moment of the most recent drain.
Always <= emit_seq(). See Self::emit_seq for how the
event loop combines the two into its watermark.
Trait Implementations§
Source§impl Debug for CapturedSink
impl Debug for CapturedSink
Source§impl Default for CapturedSink
impl Default for CapturedSink
Source§impl LogSink for CapturedSink
impl LogSink for CapturedSink
Source§fn emit(&self, lvl: Level, msg: &str)
fn emit(&self, lvl: Level, msg: &str)
Level::Off rather than relying on the caller; the macros
never pass Off, but emit() is pub.Source§fn emit_error(&self, msg: &str)
fn emit_error(&self, msg: &str)
LINESMITH_LOG=off users still
see “the statusline broke” because there’s no other channel.