Skip to main content

HandlerExt

Trait HandlerExt 

Source
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§

Source

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;
Source

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;
Source

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;
Source

fn map<F, R2>(self, f: F) -> Map<Self, F, R>
where F: Fn(R) -> R2 + Send + Sync,

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;
Source

fn map_input<F>(self, f: F) -> MapInput<Self, F>
where F: for<'tree> Fn(Input<'tree, Ctx>) -> Input<'tree, Ctx> + Send + Sync,

Transform the Input before passing it to self.

§Example
use tree_sitter_utils::{handler_fn, HandlerExt, Input};

let h = handler_fn(|input: Input<()>| input.node.kind().to_owned())
    .map_input(|mut i: Input<()>| { i.trigger_char = Some('.'); i });
let _ = h;
Source

fn and_then<F, R2>(self, f: F) -> AndThen<Self, F, R>
where F: Fn(Input<'_, Ctx>, R) -> Option<R2> + Send + Sync,

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;
Source

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;
Source

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;
Source

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;
Source

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;
Source

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;
Source

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.

Implementors§

Source§

impl<Ctx, R, T: Handler<Ctx, R>> HandlerExt<Ctx, R> for T