Skip to main content

CapturedSink

Struct CapturedSink 

Source
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

Source

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.

Source

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.

Source

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.

Source

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.

Source

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_seq lets 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.

Source

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

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for CapturedSink

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl LogSink for CapturedSink

Source§

fn emit(&self, lvl: Level, msg: &str)

Emit a level-gated diagnostic. The caller has already confirmed the level is enabled — the sink writes unconditionally. Implementations defensively no-op on Level::Off rather than relying on the caller; the macros never pass Off, but emit() is pub.
Source§

fn emit_error(&self, msg: &str)

Emit a structural-failure diagnostic. Always fires regardless of the configured level — LINESMITH_LOG=off users still see “the statusline broke” because there’s no other channel.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.