pub trait HandlerExt<Ctx, R>: Handler<Ctx, R> + Sized {
// Provided methods
fn or<H: Handler<Ctx, R>>(self, other: H) -> Or<Self, H> { ... }
fn when<P: NodePredicate<Ctx>>(self, pred: P) -> When<Self, P> { ... }
fn for_kinds(self, kinds: &'static [&'static str]) -> When<Self, KindIs> { ... }
fn map<F, R2>(self, f: F) -> Map<Self, F, R>
where F: Fn(R) -> R2 + Send + Sync { ... }
fn map_input<F>(self, f: F) -> MapInput<Self, F>
where F: for<'tree> Fn(Input<'tree, Ctx>) -> Input<'tree, Ctx> + Send + Sync { ... }
fn and_then<F, R2>(self, f: F) -> AndThen<Self, F, R>
where F: Fn(Input<'_, Ctx>, R) -> Option<R2> + Send + Sync { ... }
fn climb(self, stop_kinds: &'static [&'static str]) -> Climb<Self> { ... }
fn or_else_climb<O: Handler<Ctx, R>>(
self,
other: O,
stop_kinds: &'static [&'static str],
) -> OrElseClimb<Self, O> { ... }
fn find_ancestor(
self,
target_kinds: &'static [&'static str],
stop_kinds: &'static [&'static str],
) -> FindAncestor<Self> { ... }
fn for_children(self) -> ForChildren<Self> { ... }
fn scan_children(self) -> ScanChildren<Self> { ... }
fn boxed(self) -> BoxedHandler<Ctx, R>
where Self: 'static,
Ctx: Copy { ... }
}Expand description
Extension trait that adds combinator methods to every Handler.
Blanket-implemented for all T: Handler<Ctx, R>; not intended as a trait
object.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input, never};
let h = never::<(), u32>()
.or(handler_fn(|_: Input<()>| 42u32))
.map(|n| n.to_string());
let _ = h;Provided Methods§
Sourcefn or<H: Handler<Ctx, R>>(self, other: H) -> Or<Self, H>
fn or<H: Handler<Ctx, R>>(self, other: H) -> Or<Self, H>
Try self; if it returns None, try other.
§Example
use tree_sitter_utils::{never, handler_fn, HandlerExt, Input};
let h = never::<(), String>()
.or(handler_fn(|_: Input<()>| "fallback".to_owned()));
let _ = h;Sourcefn when<P: NodePredicate<Ctx>>(self, pred: P) -> When<Self, P>
fn when<P: NodePredicate<Ctx>>(self, pred: P) -> When<Self, P>
Run self only when pred returns true; otherwise return None.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, kind_is, Input};
let h = handler_fn(|_: Input<()>| "hit".to_owned())
.when(kind_is(&["identifier"]));
let _ = h;Sourcefn for_kinds(self, kinds: &'static [&'static str]) -> When<Self, KindIs>
fn for_kinds(self, kinds: &'static [&'static str]) -> When<Self, KindIs>
Sugar for .when(kind_is(kinds)) - only handle specific node kinds.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|_: Input<()>| "ident".to_owned())
.for_kinds(&["identifier", "type_identifier"]);
let _ = h;Sourcefn map<F, R2>(self, f: F) -> Map<Self, F, R>
fn map<F, R2>(self, f: F) -> Map<Self, F, R>
Apply f to the output value when self succeeds.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|_: Input<()>| 1u32).map(|n| n.to_string());
let _ = h;Sourcefn and_then<F, R2>(self, f: F) -> AndThen<Self, F, R>
fn and_then<F, R2>(self, f: F) -> AndThen<Self, F, R>
On success, pass (input, out) to f, which may itself return None.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|_: Input<()>| 1u32)
.and_then(|_: Input<()>, n: u32| Some(n + 1));
let _ = h;Sourcefn climb(self, stop_kinds: &'static [&'static str]) -> Climb<Self>
fn climb(self, stop_kinds: &'static [&'static str]) -> Climb<Self>
Retry self on each ancestor until it succeeds, stopping at any kind
in stop_kinds or at the root.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|input: Input<()>| {
(input.node.kind() == "module").then(|| "module".to_owned())
})
.climb(&["source_file"]);
let _ = h;Sourcefn or_else_climb<O: Handler<Ctx, R>>(
self,
other: O,
stop_kinds: &'static [&'static str],
) -> OrElseClimb<Self, O>
fn or_else_climb<O: Handler<Ctx, R>>( self, other: O, stop_kinds: &'static [&'static str], ) -> OrElseClimb<Self, O>
Try self on the original node; on None, try other on each ancestor.
§Example
use tree_sitter_utils::{never, HandlerExt, Input};
let h = never::<(), String>()
.or_else_climb(
|input: tree_sitter_utils::Input<()>| -> Option<String> {
Some(input.node.kind().to_owned())
},
&["source_file"],
);
let _ = h;Sourcefn find_ancestor(
self,
target_kinds: &'static [&'static str],
stop_kinds: &'static [&'static str],
) -> FindAncestor<Self>
fn find_ancestor( self, target_kinds: &'static [&'static str], stop_kinds: &'static [&'static str], ) -> FindAncestor<Self>
Walk up to the nearest strict ancestor in target_kinds, then run
self on that ancestor node once.
Unlike HandlerExt::climb, which retries self on every ancestor,
find_ancestor locates a specific kind first and invokes self once.
Stops (None) when a stop_kinds node or the root is reached.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|inp: Input<()>| inp.node.kind().to_owned())
.find_ancestor(&["argument_list"], &["program"]);
let _ = h;Sourcefn for_children(self) -> ForChildren<Self>
fn for_children(self) -> ForChildren<Self>
Apply self to every named child, collect all Some(r) into a
Vec<R>, and return Some(vec) (never None).
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};
let h = handler_fn(|inp: Input<()>| inp.node.kind().to_owned())
.for_children();
let _ = h;Sourcefn scan_children(self) -> ScanChildren<Self>
fn scan_children(self) -> ScanChildren<Self>
Apply self to each named child in order; return the first
Some(r), or None if no child matches.
§Example
use tree_sitter_utils::{Input, HandlerExt};
let h = (|inp: Input<()>| -> Option<String> {
(inp.node.kind() == "identifier").then(|| inp.node.kind().to_owned())
})
.scan_children();
let _ = h;Sourcefn boxed(self) -> BoxedHandler<Ctx, R>where
Self: 'static,
Ctx: Copy,
fn boxed(self) -> BoxedHandler<Ctx, R>where
Self: 'static,
Ctx: Copy,
Erase the concrete type into a BoxedHandler for dynamic dispatch.
§Example
use tree_sitter_utils::{handler_fn, HandlerExt, BoxedHandler, Input};
let h: BoxedHandler<(), String> =
handler_fn(|_: Input<()>| "hi".to_owned()).boxed();
let _ = h;Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.