Skip to main content

EmitterView

Struct EmitterView 

Source
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 — since CstEmitter::cst_token was 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 that commit_token was 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 forwarded emit_lexer_error records 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>,

Source

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.

Source

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.

Source

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>
where L: Lexer<'inp>, E: Emitter<'inp, L, Lang>,

Source

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.

Source

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.

Source

pub fn emit_error( &mut self, err: Spanned<E::Error, L::Span>, ) -> Result<(), E::Error>

Emits an application error — Emitter::emit_error, forwarded.

Source

pub fn emit_warning( &mut self, warning: Spanned<E::Error, L::Span>, ) -> Result<(), E::Error>

Emits a warning — Emitter::emit_warning, forwarded.

Source

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.

Source

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.

Source

pub fn exit_label(&mut self)

Pops the innermost diagnostic label — Emitter::exit_label, forwarded.

Source

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.

Source

pub fn cst_start(&mut self, kind: u16) -> EventMark
where E: CstEmitter<'inp, L, Lang>,

Opens a CST node of kindCstEmitter::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.

Source

pub fn cst_finish(&mut self, kind: u16)
where E: CstEmitter<'inp, L, Lang>,

Closes the innermost open CST node — CstEmitter::cst_finish, forwarded.

Source

pub fn cst_demote(&mut self, mark: EventMark, kind: u16)
where E: CstEmitter<'inp, L, Lang>,

Un-opens the node started at markCstEmitter::cst_demote, forwarded.

Source

pub fn cst_mark(&mut self) -> EventMark
where E: CstEmitter<'inp, L, Lang>,

Appends a retro-wrap anchor — CstEmitter::cst_mark, forwarded.

Source

pub fn cst_start_at(&mut self, mark: EventMark, kind: u16)
where E: CstEmitter<'inp, L, Lang>,

Retro-opens a node of kind at markCstEmitter::cst_start_at, forwarded.

Source

pub fn emit_too_few( &mut self, err: TooFew<L::Span, Lang>, ) -> Result<(), E::Error>
where E: TooFewEmitter<'inp, L, Lang>,

Source

pub fn emit_too_many( &mut self, err: TooMany<L::Span, Lang>, ) -> Result<(), E::Error>
where E: TooManyEmitter<'inp, L, Lang>,

Source

pub fn emit_full_container( &mut self, err: FullContainer<L::Span, Lang>, ) -> Result<(), E::Error>
where E: FullContainerEmitter<'inp, L, Lang>,

Source

pub fn emit_missing_separator( &mut self, name: CowStr, err: MissingTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: SeparatedEmitter<'inp, L, Lang>,

Source

pub fn emit_missing_element( &mut self, err: MissingSyntaxOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: SeparatedEmitter<'inp, L, Lang>,

Source

pub fn emit_missing_leading_separator( &mut self, name: CowStr, err: MissingTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: MissingLeadingSeparatorEmitter<'inp, L, Lang>,

Source

pub fn emit_missing_trailing_separator( &mut self, name: CowStr, err: MissingTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: MissingTrailingSeparatorEmitter<'inp, L, Lang>,

Source

pub fn emit_unexpected_leading_separator( &mut self, name: CowStr, err: UnexpectedTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: UnexpectedLeadingSeparatorEmitter<'inp, L, Lang>,

Source

pub fn emit_unexpected_trailing_separator( &mut self, name: CowStr, err: UnexpectedTokenOf<'inp, L, Lang>, ) -> Result<(), E::Error>
where E: UnexpectedTrailingSeparatorEmitter<'inp, L, Lang>,

Source

pub fn emit_unclosed<Delimiter>( &mut self, err: Unclosed<Delimiter, L::Span, Lang>, ) -> Result<(), E::Error>
where E: UnclosedEmitter<'inp, L, Lang>,

Source

pub 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.
Source

pub 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.

Trait Implementations§

Source§

impl<'inp, L, E, Lang: ?Sized> Debug for EmitterView<'_, 'inp, L, E, Lang>
where L: Lexer<'inp>,

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, 'inp, L, E, Lang = ()> !UnwindSafe for EmitterView<'a, 'inp, L, E, Lang>

§

impl<'a, 'inp, L, E, Lang> Freeze for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: Freeze, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: Freeze, Lang: ?Sized,

§

impl<'a, 'inp, L, E, Lang> RefUnwindSafe for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: RefUnwindSafe, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: RefUnwindSafe, Lang: ?Sized,

§

impl<'a, 'inp, L, E, Lang> Send for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: Send, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: Send, Lang: ?Sized,

§

impl<'a, 'inp, L, E, Lang> Sync for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: Sync, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: Sync, Lang: ?Sized,

§

impl<'a, 'inp, L, E, Lang> Unpin for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: Unpin, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: Unpin, Lang: ?Sized,

§

impl<'a, 'inp, L, E, Lang> UnsafeUnpin for EmitterView<'a, 'inp, L, E, Lang>
where &'a mut E: UnsafeUnpin, PhantomData<(&'inp (), fn() -> L, fn() -> *const Lang)>: UnsafeUnpin, Lang: ?Sized,

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.