Skip to main content

tree_sitter_utils/
handler.rs

1//! The [`Handler`] trait and blanket implementations.
2
3use crate::input::Input;
4
5/// The result type returned by every handler — `Some(out)` on success,
6/// `None` to signal "this handler does not apply here".
7pub type HandlerResult<R> = Option<R>;
8
9/// Core abstraction: maps an [`Input`] to an optional output value.
10///
11/// Implement this trait to create a custom handler, or use the
12/// free-function constructors ([`crate::handler_fn`], [`crate::always`], …)
13/// and the combinator extension methods provided by [`crate::HandlerExt`].
14///
15/// Lifetimes are on the `handle` method, not on the trait itself, so a
16/// single handler instance can be reused across nodes from different trees.
17///
18/// # Example
19///
20/// ```rust
21/// use tree_sitter_utils::{Handler, Input, HandlerResult};
22///
23/// struct MyHandler;
24///
25/// impl<Ctx: Copy> Handler<Ctx, String> for MyHandler {
26///     fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<String> {
27///         Some(input.node.kind().to_owned())
28///     }
29/// }
30/// ```
31pub trait Handler<Ctx, R>: Send + Sync {
32    /// Attempt to produce an output value for the given input.
33    ///
34    /// Returns `None` when this handler does not apply.
35    fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<R>;
36}
37
38/// Blanket implementation: any `Fn(Input<'_, Ctx>) -> Option<R>` is a handler.
39///
40/// # Example
41///
42/// ```rust
43/// use tree_sitter_utils::{Handler, Input};
44///
45/// fn use_handler<H: Handler<(), String>>(h: &H) { let _ = h; }
46///
47/// let f = |input: Input<()>| -> Option<String> {
48///     Some(input.node.kind().to_owned())
49/// };
50/// use_handler(&f);
51/// ```
52impl<Ctx, R, F> Handler<Ctx, R> for F
53where
54    F: Fn(Input<'_, Ctx>) -> Option<R> + Send + Sync,
55{
56    #[inline]
57    fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<R> {
58        self(input)
59    }
60}