pub trait LexHandler: Send + Sync {
// Provided methods
fn on_label(&self, _ctx: &LabelCtx) { ... }
fn on_validate(
&self,
_ctx: &LabelCtx,
) -> Result<Vec<Diagnostic>, HandlerError> { ... }
fn on_resolve(
&self,
_ctx: &LabelCtx,
) -> Result<Option<WireNode>, HandlerError> { ... }
fn on_ir_build(
&self,
_ctx: &LabelCtx,
) -> Result<Option<WireNode>, HandlerError> { ... }
fn on_render(
&self,
_ctx: &LabelCtx,
_fmt: Format,
) -> Result<Option<RenderOut>, HandlerError> { ... }
fn on_hover(&self, _ctx: &LabelCtx) -> Result<Option<Hover>, HandlerError> { ... }
fn on_completion(
&self,
_ctx: &LabelCtx,
) -> Result<Vec<Completion>, HandlerError> { ... }
fn on_code_action(
&self,
_ctx: &LabelCtx,
) -> Result<Vec<CodeAction>, HandlerError> { ... }
fn on_format(
&self,
_ctx: &FormatCtx,
) -> Result<Option<LexAnnotationOut>, HandlerError> { ... }
}Expand description
The hook-event interface a Lex extension implements.
Every method has a default implementation that returns the identity
(Ok(None), Ok(Vec::new()), ()), so an extension only needs to
override the methods it cares about. An empty impl LexHandler for Foo {}
is a no-op handler that compiles and runs.
Provided Methods§
Sourcefn on_label(&self, _ctx: &LabelCtx)
fn on_label(&self, _ctx: &LabelCtx)
Informational notification fired during the analyse phase. No response is expected. Use this for handlers that maintain external state (caches, indices, link graphs).
Sourcefn on_validate(&self, _ctx: &LabelCtx) -> Result<Vec<Diagnostic>, HandlerError>
fn on_validate(&self, _ctx: &LabelCtx) -> Result<Vec<Diagnostic>, HandlerError>
Returns diagnostics for a labelled node. Fires during analyse, after resolve.
Sourcefn on_resolve(&self, _ctx: &LabelCtx) -> Result<Option<WireNode>, HandlerError>
fn on_resolve(&self, _ctx: &LabelCtx) -> Result<Option<WireNode>, HandlerError>
Returns an AST replacement subtree, which the host splices into the
parent in place of the labelled node. Fires during the resolve phase,
before analyse. Ok(None) leaves the original node in place.
on_resolve is the AST-substitution lifecycle: the canonical example
is lex.include, which splices the resolved file’s content into the
host document. Verbatim labels that hydrate into typed IR nodes
(lex.tabular.table, lex.media.*) belong on
on_ir_build instead — that hook is the
IR-construction lifecycle and is invoked during from_lex IR build.
Sourcefn on_ir_build(&self, _ctx: &LabelCtx) -> Result<Option<WireNode>, HandlerError>
fn on_ir_build(&self, _ctx: &LabelCtx) -> Result<Option<WireNode>, HandlerError>
Returns a typed wire node consumed by the host while building its
in-memory IR from the parsed source. Fires during IR construction
(from_lex), strictly after parsing and strictly before render.
Ok(None) falls back to the host’s generic verbatim/annotation IR.
This is the lifecycle hook for content-typing labels — the
canonical examples are lex.tabular.table (verbatim body → typed
WireNode::Table) and lex.media.{image,video,audio} (params →
typed WireNode::Image|Video|Audio). Pair an on_ir_build hook
with an on_render hook on the same schema to
give one label both an IR shape and per-format serialization
behaviour through the unified registry surface (#615).
IR-build hooks do not receive the host’s lex-core AST: they
see only the parsed verbatim payload (label + params + body) via
LabelCtx. Coupling content-typing to the IR phase rather than
to parsing keeps a buggy or slow handler from corrupting the
parser, and gives extension authors a single registration point
for both lifecycle phases.
Sourcefn on_render(
&self,
_ctx: &LabelCtx,
_fmt: Format,
) -> Result<Option<RenderOut>, HandlerError>
fn on_render( &self, _ctx: &LabelCtx, _fmt: Format, ) -> Result<Option<RenderOut>, HandlerError>
Returns the labelled node’s representation in a target format. Fires
during lexd convert or library-driven rendering. Ok(None) falls
back to default rendering of the underlying node.
Sourcefn on_hover(&self, _ctx: &LabelCtx) -> Result<Option<Hover>, HandlerError>
fn on_hover(&self, _ctx: &LabelCtx) -> Result<Option<Hover>, HandlerError>
Returns hover content for a labelled node. Fires in response to
textDocument/hover LSP requests.
Sourcefn on_completion(
&self,
_ctx: &LabelCtx,
) -> Result<Vec<Completion>, HandlerError>
fn on_completion( &self, _ctx: &LabelCtx, ) -> Result<Vec<Completion>, HandlerError>
Returns completion items for a position inside a labelled node’s
params or body. Fires in response to textDocument/completion.
Sourcefn on_code_action(
&self,
_ctx: &LabelCtx,
) -> Result<Vec<CodeAction>, HandlerError>
fn on_code_action( &self, _ctx: &LabelCtx, ) -> Result<Vec<CodeAction>, HandlerError>
Returns code actions for a labelled node. Fires in response to
textDocument/codeAction.
Sourcefn on_format(
&self,
_ctx: &FormatCtx,
) -> Result<Option<LexAnnotationOut>, HandlerError>
fn on_format( &self, _ctx: &FormatCtx, ) -> Result<Option<LexAnnotationOut>, HandlerError>
Returns the Lex-source representation of a typed AST subtree
owned by this handler’s namespace — the inverse of
on_resolve, and the reverse-direction
sibling of on_render for the Lex target
format.
Phase 4a of #570 ships this trait method, the FormatCtx /
LexAnnotationOut wire types, and the
Registry::dispatch_format
entry point. Phase 4b implements on_format in the built-in
lex.tabular.* / lex.media.* handlers. Production call
sites in to_lex.rs and lexd format get wired in a Phase 4b
follow-up — until that lands, the hook is invocable through
the registry (tests + library embedders use it) but no
built-in pass dispatches through it yet, so a handler
implementing on_format will be exercised by direct
Registry::dispatch_format callers only.
Ok(None) lets the host fall back to its built-in formatter
for the underlying node kind — there is no separate
“not handled” error code. See comms/specs/proposals/lex-extension-wire.lex
§4.8 for the full wire contract.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".