Skip to main content

LogSink

Trait LogSink 

Source
pub trait LogSink: Send + Sync {
    // Required methods
    fn emit(&self, lvl: Level, msg: &str);
    fn emit_error(&self, msg: &str);
}
Expand description

Pluggable destination for diagnostic emissions. The default StderrSink preserves the linesmith [<level>]: <msg> format external scripts grep for; the TUI swaps in a CapturedSink for the duration of the alt-screen so macro emissions land in the warnings panel instead of corrupting the painted frame.

&self (not &mut self) so a sink instance can be shared via Arc<dyn LogSink>. The Send + Sync bound is what Arc<dyn _> requires and lets background plugin emitters share the slot safely with the render thread. The active-sink slot is an RwLock: emits take read locks (concurrent) and install_sink takes the write lock, which waits for in-flight emits to drain before swapping. This applies only to dispatches that go through emit / emit_error — a thread that holds its own Arc<dyn LogSink> (the prior returned by install_sink, or a future plugin handle) can still drive that sink directly after a swap.

Implementations must not call back into emit / emit_error or the lsm_warn! / lsm_debug! / lsm_error! macros from within their own emit / emit_error. The slot’s read lock is held across the dispatch, and std::sync::RwLock’s reentrancy is platform-defined — a recursive read can deadlock against a pending install_sink on writer-preferring runtimes (musl, Windows SRW). lsm-261p tracks evaluating a fair RwLock so this invariant can relax.

Required Methods§

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.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§