pub trait Channel {
// Required methods
fn report(&self, report: &Report);
fn ask(&self, question: &Question);
fn withdraw(&self, about: &str);
fn answers(&self) -> Vec<Answer>;
// Provided methods
fn insist(&self, report: &Report) { ... }
fn stay_until_seen(&self) { ... }
}Expand description
How the tool speaks, and how it is answered.
Object-safe on purpose: main picks one implementation at startup from what
the machine turns out to have, and the engine holds it as a reference in
crate::outside::Outside.
Required Methods§
Sourcefn ask(&self, question: &Question)
fn ask(&self, question: &Question)
Ask something, and return. The answer, if one comes, arrives through
answers.
Sourcefn withdraw(&self, about: &str)
fn withdraw(&self, about: &str)
Take back a question that no longer applies, named by its about.
The case is a session that resolved itself while its question was still sitting in somebody’s message list — a lingering editor’s last save landing (concept 8), or the same question answered at the command line. A button that would act on a session that has gone is answerable and pointless, and the answer would have to be a refusal.
Provided Methods§
Sourcefn insist(&self, report: &Report)
fn insist(&self, report: &Report)
Say something in a way that cannot be missed, because something was refused and the person is owed an explanation for it.
Not a question, and it does not block the caller. By the time this
is called the refusal has already happened — nothing is waiting on an
answer, and there is nothing to decide. What it buys over
report is that a notification can be missed and this
one must not be: a double-click that produced no document and no
message is the tool looking broken at the exact moment it worked.
The default is report, which is right wherever the
channel has nothing louder. Concept 12 gives Windows a native message
box and that is where this becomes a dialog.
Sourcefn stay_until_seen(&self)
fn stay_until_seen(&self)
Wait for anything this channel put on the screen that belongs to this process, before the process ends.
The other half of insist, and it exists because a
refusal was silently lost. Measured against the installed package on
2026-09-06: a container whose content file is a program, double-clicked with
no instance already running, produced nothing at all — no box, no window,
the process gone inside 400ms. With an instance running it produced the
box every time. The difference is entirely who was left alive: the
Windows box is a thread, because the resident loop must not stop pumping
watchers for as long as somebody leaves a dialog up, and an invocation
that refused and held nothing returns immediately — taking the thread
down with it before it had drawn.
So the rule is not show it but do not leave while it is up, and that is what this is. A channel whose output outlives the process — a toast, a freedesktop notification, a line already written to a terminal — has nothing to wait for, which is why the default does nothing.
Called at the points where the process is about to end, not after each
insist: the resident loop insists mid-flight and must
carry on, and the whole reason the box is on a thread is so that it can.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".