pub struct EmitterView<'a, 'inp, L, E, Lang: ?Sized = ()>where
L: Lexer<'inp>,{ /* private fields */ }Expand description
The emitter’s operations, lent to a callback — never the emitter.
Handed by value to every public callback that used to receive &mut Ctx::Emitter:
Decision::decide, the peek_then family’s handlers, and the
token-level pratt folds. The methods carry the emitter’s own names, so a body written against
&mut E keeps every statement it had.
§It is not an emitter, and that is the point
EmitterView implements no emitter trait, does not Deref, and hands back
no &mut E. A wrapper built around one can forward nothing, so it cannot occupy the emitter
slot of a second parse over a foreign buffer — the wrong-source class the lossless drivers’
pinned slot closes at the entry, and which a callback parameter used to re-open from inside.
See the module documentation for the class and for the four members deliberately withheld.
emitter_ref hands back &E — the door for reading a concrete
emitter’s own state mid-parse (a collecting emitter’s diagnostics, a counter, a label stack). A
shared reference cannot re-enter an emitter slot either: every recording method on the trait
family takes &mut self, so a wrapper built around &E can forward none of them.
§The bound of that claim
“Implements no emitter trait” is a fact about this crate, and the orphan rules do not make
it universal: a downstream crate whose own lexer type appears in the parameter list may write
impl Emitter<'_, MyLexer<'_>> for EmitterView<'_, '_, MyLexer<'_>, Sink<..>> — the trait and
this type are both foreign, but MyLexer is local and no uncovered type parameter precedes it
— and install that over a second buffer.
What such an implementation can forward is bounded by the surface below, and the two members that decide what a source byte is are not on it:
Emitter::commit_token, the auto-emission chokepoint and — sinceCstEmitter::cst_tokenwas deleted — the only producer of token events. A token is what pairs a span with a byte, so a second parse driven this way contributes no token, no span and no byte of its own buffer.Emitter::commit_lexer_error, the only producer of gap-coverage evidence. Saying thatcommit_tokenwas the only door onto the sink’s structural machinery was, for one round, incomplete: a recorded lexer error’s span licenses a gap tile, so a foreign parse whose input layer reported its own refusals through such a wrapper was excusing bytes of this sink’s buffer that this parse never covered. The forwardedemit_lexer_errorrecords no coverage span, so that route now delivers a diagnostic and nothing structural.
What is left is the diagnostic and node channels — which a callback body can already reach directly through this same surface, by design — and the tree still materializes over the buffer its sink was minted from, covered by exactly the bytes that parse’s own tokens and its own lexer’s refusals account for.
Implementations§
Source§impl<'a, 'inp, L, E, Lang: ?Sized> EmitterView<'a, 'inp, L, E, Lang>where
L: Lexer<'inp>,
impl<'a, 'inp, L, E, Lang: ?Sized> EmitterView<'a, 'inp, L, E, Lang>where
L: Lexer<'inp>,
Sourcepub const fn new(emitter: &'a mut E) -> Self
pub const fn new(emitter: &'a mut E) -> Self
Lends emitter’s operations.
§Why this is public, and grants nothing
It takes a &mut E — so a caller who can build a view already held the very thing the view
exists to withhold, and gains no reach by wrapping it. Inside a parse there is no &mut Ctx::Emitter to pass: the handle’s accessor is crate-private and the callback traits hand
out views, which is the wall. This constructor is for the other side of it: exercising a
Decision body, a peek_then handler, or a token-level pratt fold
directly, over an emitter the test owns — EmitterView::new(&mut Verbose::new()), or
&mut () for a fold that ignores the parameter. Without it those bodies would only be
reachable through a whole parse, which is a rewrite of every unit test they have.
Sourcepub fn reborrow(&mut self) -> EmitterView<'_, 'inp, L, E, Lang>
pub fn reborrow(&mut self) -> EmitterView<'_, 'inp, L, E, Lang>
Reborrows this view for a shorter life.
The view is not Copy — it holds a &mut — so a body that hands it to two helpers in
sequence needs this, exactly as it would have needed &mut *emitter before.
Sourcepub const fn emitter_ref(&self) -> &E
pub const fn emitter_ref(&self) -> &E
The emitter, by shared reference — for reading a concrete emitter’s own state while the parse is running (a collecting emitter’s recorded diagnostics, a counter, a label stack).
Shared on purpose, and the receiver is the whole of the difference: every method that
records anything and every method that captures a mark takes &mut self, so a wrapper
type built around this reference can forward none of them, cannot stand in an emitter slot,
and cannot mint a checkpoint the input layer never took (Emitter::checkpoint took
&self through 0.9.1 — al8n/tokora#257). To emit, call the forwarding methods on this view.
The same residue InputRef::emitter_ref states applies: E
is the caller’s type, and what an emitter does to its own state through its own cells is
its own to account for.
Source§impl<'inp, L, E, Lang: ?Sized> EmitterView<'_, 'inp, L, E, Lang>
impl<'inp, L, E, Lang: ?Sized> EmitterView<'_, 'inp, L, E, Lang>
Sourcepub fn emit_lexer_error(
&mut self,
err: Spanned<<L::Token as Token<'inp>>::Error, L::Span>,
) -> Result<(), E::Error>
pub fn emit_lexer_error( &mut self, err: Spanned<<L::Token as Token<'inp>>::Error, L::Span>, ) -> Result<(), E::Error>
Emits a lexer error — Emitter::emit_lexer_error, forwarded.
The input layer’s own lexer-error reports are deduped against a watermark; a report raised here is not, so a caller re-reporting a region the layer already reported produces two diagnostics rather than one. Noisy, never silent.
§It reports; it does not license
A recording Sink tiles a source byte no committed token covers only
where a lexer error the input layer raised covers it. A report raised here carries a span
the caller chose, with nothing consumed for it, so the sink records the diagnostic and no
coverage span: an uncovered byte stays uncovered and finish still refuses it
(FinishError::UncoveredGap). The evidence door is
Emitter::commit_lexer_error, which is deliberately not on this surface.
Sourcepub fn emit_unexpected_token(
&mut self,
err: UnexpectedTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>
pub fn emit_unexpected_token( &mut self, err: UnexpectedTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
Emits an unexpected-token report — Emitter::emit_unexpected_token, forwarded.
This does not publish the front-report watermark the input layer maintains for the token at the stream front, so a later close-miss report about the same token is not suppressed by it. Same direction as above: an extra diagnostic, never a missing one.
Sourcepub fn emit_error(
&mut self,
err: Spanned<E::Error, L::Span>,
) -> Result<(), E::Error>
pub fn emit_error( &mut self, err: Spanned<E::Error, L::Span>, ) -> Result<(), E::Error>
Emits an application error — Emitter::emit_error, forwarded.
Sourcepub fn emit_warning(
&mut self,
warning: Spanned<E::Error, L::Span>,
) -> Result<(), E::Error>
pub fn emit_warning( &mut self, warning: Spanned<E::Error, L::Span>, ) -> Result<(), E::Error>
Emits a warning — Emitter::emit_warning, forwarded.
Sourcepub fn emit_skipped_region(
&mut self,
span: L::Span,
skipped: usize,
) -> Result<(), E::Error>
pub fn emit_skipped_region( &mut self, span: L::Span, skipped: usize, ) -> Result<(), E::Error>
Emits a recovery-hole note — Emitter::emit_skipped_region, forwarded.
Span semantics. Under a CST sink this call also has a structural effect: the hole’s
buffered tokens are bracketed in an error node, and that bracket covers only the hole
tokens that settled within the transaction reporting the hole — at or above the
youngest live checkpoint. A wider span still reaches the diagnostic channel verbatim;
it exerts no structural authority over tokens committed before that checkpoint, because
checkpoint marks are event-log positions and a node spliced beneath one would rename it.
Sourcepub fn enter_label(&mut self, label: &'static str)
pub fn enter_label(&mut self, label: &'static str)
Pushes a diagnostic label — Emitter::enter_label, forwarded.
Pairs with exit_label; prefer labelled, which
pairs them through a drop guard.
Sourcepub fn exit_label(&mut self)
pub fn exit_label(&mut self)
Pops the innermost diagnostic label — Emitter::exit_label, forwarded.
Sourcepub fn bound_source(&self) -> Option<SourceIdentity>
pub fn bound_source(&self) -> Option<SourceIdentity>
The source the emitter is bound to, if any — Emitter::bound_source, forwarded.
A query, not an emission: it answers for anyone who can reach the emitter, which is why no sink-side witness built on it can encode who asked.
Sourcepub fn cst_start(&mut self, kind: u16) -> EventMarkwhere
E: CstEmitter<'inp, L, Lang>,
pub fn cst_start(&mut self, kind: u16) -> EventMarkwhere
E: CstEmitter<'inp, L, Lang>,
Opens a CST node of kind — CstEmitter::cst_start, forwarded.
Raw transport: pair it with cst_finish through a both-exits bracket, or
use the node-shaped combinators. The returned mark is the failing exit’s handle — spend
it on cst_demote.
Sourcepub fn cst_finish(&mut self, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
pub fn cst_finish(&mut self, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
Closes the innermost open CST node — CstEmitter::cst_finish, forwarded.
Sourcepub fn cst_demote(&mut self, mark: EventMark, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
pub fn cst_demote(&mut self, mark: EventMark, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
Un-opens the node started at mark — CstEmitter::cst_demote, forwarded.
Sourcepub fn cst_mark(&mut self) -> EventMarkwhere
E: CstEmitter<'inp, L, Lang>,
pub fn cst_mark(&mut self) -> EventMarkwhere
E: CstEmitter<'inp, L, Lang>,
Appends a retro-wrap anchor — CstEmitter::cst_mark, forwarded.
Sourcepub fn cst_start_at(&mut self, mark: EventMark, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
pub fn cst_start_at(&mut self, mark: EventMark, kind: u16)where
E: CstEmitter<'inp, L, Lang>,
Retro-opens a node of kind at mark — CstEmitter::cst_start_at, forwarded.
Sourcepub fn emit_too_few(
&mut self,
err: TooFew<L::Span, Lang>,
) -> Result<(), E::Error>where
E: TooFewEmitter<'inp, L, Lang>,
pub fn emit_too_few(
&mut self,
err: TooFew<L::Span, Lang>,
) -> Result<(), E::Error>where
E: TooFewEmitter<'inp, L, Lang>,
TooFewEmitter::emit_too_few, forwarded.
Sourcepub fn emit_too_many(
&mut self,
err: TooMany<L::Span, Lang>,
) -> Result<(), E::Error>where
E: TooManyEmitter<'inp, L, Lang>,
pub fn emit_too_many(
&mut self,
err: TooMany<L::Span, Lang>,
) -> Result<(), E::Error>where
E: TooManyEmitter<'inp, L, Lang>,
TooManyEmitter::emit_too_many, forwarded.
Sourcepub fn emit_full_container(
&mut self,
err: FullContainer<L::Span, Lang>,
) -> Result<(), E::Error>where
E: FullContainerEmitter<'inp, L, Lang>,
pub fn emit_full_container(
&mut self,
err: FullContainer<L::Span, Lang>,
) -> Result<(), E::Error>where
E: FullContainerEmitter<'inp, L, Lang>,
FullContainerEmitter::emit_full_container, forwarded.
Sourcepub fn emit_missing_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: SeparatedEmitter<'inp, L, Lang>,
pub fn emit_missing_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: SeparatedEmitter<'inp, L, Lang>,
SeparatedEmitter::emit_missing_separator, forwarded.
Sourcepub fn emit_missing_element(
&mut self,
err: MissingSyntaxOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: SeparatedEmitter<'inp, L, Lang>,
pub fn emit_missing_element(
&mut self,
err: MissingSyntaxOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: SeparatedEmitter<'inp, L, Lang>,
SeparatedEmitter::emit_missing_element, forwarded.
Sourcepub fn emit_missing_leading_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: MissingLeadingSeparatorEmitter<'inp, L, Lang>,
pub fn emit_missing_leading_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: MissingLeadingSeparatorEmitter<'inp, L, Lang>,
Sourcepub fn emit_missing_trailing_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: MissingTrailingSeparatorEmitter<'inp, L, Lang>,
pub fn emit_missing_trailing_separator(
&mut self,
name: CowStr,
err: MissingTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: MissingTrailingSeparatorEmitter<'inp, L, Lang>,
Sourcepub fn emit_unexpected_leading_separator(
&mut self,
name: CowStr,
err: UnexpectedTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: UnexpectedLeadingSeparatorEmitter<'inp, L, Lang>,
pub fn emit_unexpected_leading_separator(
&mut self,
name: CowStr,
err: UnexpectedTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: UnexpectedLeadingSeparatorEmitter<'inp, L, Lang>,
Sourcepub fn emit_unexpected_trailing_separator(
&mut self,
name: CowStr,
err: UnexpectedTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: UnexpectedTrailingSeparatorEmitter<'inp, L, Lang>,
pub fn emit_unexpected_trailing_separator(
&mut self,
name: CowStr,
err: UnexpectedTokenOf<'inp, L, Lang>,
) -> Result<(), E::Error>where
E: UnexpectedTrailingSeparatorEmitter<'inp, L, Lang>,
Sourcepub fn emit_unclosed<Delimiter>(
&mut self,
err: Unclosed<Delimiter, L::Span, Lang>,
) -> Result<(), E::Error>where
E: UnclosedEmitter<'inp, L, Lang>,
pub fn emit_unclosed<Delimiter>(
&mut self,
err: Unclosed<Delimiter, L::Span, Lang>,
) -> Result<(), E::Error>where
E: UnclosedEmitter<'inp, L, Lang>,
UnclosedEmitter::emit_unclosed, forwarded.
Sourcepub fn emit_unexpected_end_of_lhs(
&mut self,
err: UnexpectedEoLhs<L::Offset, Lang>,
) -> Result<(), E::Error>where
E: PrattEmitter<'inp, L, Lang>,
Available on crate feature pratt only.
pub fn emit_unexpected_end_of_lhs(
&mut self,
err: UnexpectedEoLhs<L::Offset, Lang>,
) -> Result<(), E::Error>where
E: PrattEmitter<'inp, L, Lang>,
pratt only.PrattEmitter::emit_unexpected_end_of_lhs, forwarded.
Sourcepub fn emit_unexpected_end_of_rhs(
&mut self,
err: UnexpectedEoRhs<L::Offset, Lang>,
) -> Result<(), E::Error>where
E: PrattEmitter<'inp, L, Lang>,
Available on crate feature pratt only.
pub fn emit_unexpected_end_of_rhs(
&mut self,
err: UnexpectedEoRhs<L::Offset, Lang>,
) -> Result<(), E::Error>where
E: PrattEmitter<'inp, L, Lang>,
pratt only.PrattEmitter::emit_unexpected_end_of_rhs, forwarded.