Skip to main content

tree_sitter_utils/
constructors.rs

1//! Free-function handler constructors.
2
3use crate::handler::{Handler, HandlerResult};
4use crate::input::Input;
5
6// ---------------------------------------------------------------------------
7// handler_fn
8// ---------------------------------------------------------------------------
9
10/// Wrap an infallible function as a [`Handler`] that always returns `Some`.
11///
12/// Use this when your mapping function cannot fail.
13///
14/// # Example
15///
16/// ```rust
17/// use tree_sitter_utils::{handler_fn, Handler, Input};
18///
19/// let h = handler_fn(|input: Input<()>| input.node.kind().to_owned());
20/// let _ = h;
21/// ```
22pub fn handler_fn<Ctx, R, F>(f: F) -> HandlerFn<F>
23where
24    F: Fn(Input<'_, Ctx>) -> R + Send + Sync,
25{
26    HandlerFn(f)
27}
28
29/// Handler produced by [`handler_fn`].
30///
31/// # Example
32///
33/// ```rust
34/// use tree_sitter_utils::{handler_fn, Input};
35/// let h = handler_fn(|_: Input<()>| 42u32);
36/// let _ = h;
37/// ```
38pub struct HandlerFn<F>(F);
39
40impl<Ctx, R, F> Handler<Ctx, R> for HandlerFn<F>
41where
42    F: Fn(Input<'_, Ctx>) -> R + Send + Sync,
43    Ctx: Copy,
44{
45    #[inline]
46    fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<R> {
47        Some((self.0)(input))
48    }
49}
50
51// ---------------------------------------------------------------------------
52// never / always
53// ---------------------------------------------------------------------------
54
55/// A handler that always returns `None`.
56///
57/// # Example
58///
59/// ```rust
60/// use tree_sitter_utils::{never, HandlerExt, handler_fn, Input};
61///
62/// let h = never::<(), String>()
63///     .or(handler_fn(|_: Input<()>| "fallback".to_owned()));
64/// let _ = h;
65/// ```
66pub fn never<Ctx, R>() -> Never<Ctx, R> {
67    Never(std::marker::PhantomData)
68}
69
70/// Handler produced by [`never()`].
71///
72/// # Example
73///
74/// ```rust
75/// use tree_sitter_utils::never;
76/// let h = never::<(), u32>();
77/// let _ = h;
78/// ```
79pub struct Never<Ctx, R>(std::marker::PhantomData<fn(Ctx) -> R>);
80
81impl<Ctx, R> Handler<Ctx, R> for Never<Ctx, R> {
82    #[inline]
83    fn handle<'tree>(&self, _input: Input<'tree, Ctx>) -> HandlerResult<R> {
84        None
85    }
86}
87
88/// A handler that always returns `Some(value.clone())`.
89///
90/// # Example
91///
92/// ```rust
93/// use tree_sitter_utils::always;
94/// let h = always::<(), _>("hello".to_owned());
95/// let _ = h;
96/// ```
97pub fn always<Ctx, R: Clone + Send + Sync>(value: R) -> Always<R> {
98    Always(value)
99}
100
101/// Handler produced by [`always`].
102///
103/// # Example
104///
105/// ```rust
106/// use tree_sitter_utils::always;
107/// let h = always::<(), u32>(42);
108/// let _ = h;
109/// ```
110pub struct Always<R>(pub R);
111
112impl<R> Always<R> {
113    /// Construct an [`Always`] handler in a `const` / `static` context.
114    ///
115    /// # Example
116    ///
117    /// ```rust
118    /// use tree_sitter_utils::constructors::Always;
119    /// static H: Always<u32> = Always::new_const(42u32);
120    /// ```
121    pub const fn new_const(value: R) -> Self {
122        Always(value)
123    }
124}
125
126impl<Ctx, R: Clone + Send + Sync> Handler<Ctx, R> for Always<R> {
127    #[inline]
128    fn handle<'tree>(&self, _input: Input<'tree, Ctx>) -> HandlerResult<R> {
129        Some(self.0.clone())
130    }
131}
132
133// ---------------------------------------------------------------------------
134// dispatch_on_kind
135// ---------------------------------------------------------------------------
136
137/// Build a handler that dispatches on `node.kind()` via a static lookup table.
138///
139/// Entries are tried in order; the first matching kind wins.
140///
141/// # Example
142///
143/// ```rust
144/// use tree_sitter_utils::dispatch_on_kind;
145/// // let h = dispatch_on_kind(&[("identifier", &my_handler)]);
146/// let _ = dispatch_on_kind::<(), u32>(&[]);
147/// ```
148pub fn dispatch_on_kind<Ctx: 'static, R: 'static>(
149    table: &'static [(&'static str, &'static dyn Handler<Ctx, R>)],
150) -> DispatchOnKind<Ctx, R> {
151    DispatchOnKind { table }
152}
153
154/// Handler produced by [`dispatch_on_kind`].
155///
156/// # Example
157///
158/// ```rust
159/// use tree_sitter_utils::dispatch_on_kind;
160/// let h = dispatch_on_kind::<(), u32>(&[]);
161/// let _ = h;
162/// ```
163pub struct DispatchOnKind<Ctx: 'static, R: 'static> {
164    /// The static dispatch table.
165    pub table: &'static [(&'static str, &'static dyn Handler<Ctx, R>)],
166}
167
168impl<Ctx, R> Handler<Ctx, R> for DispatchOnKind<Ctx, R>
169where
170    Ctx: Copy + 'static,
171    R: 'static,
172{
173    fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<R> {
174        let kind = input.node.kind();
175        for (k, h) in self.table {
176            if *k == kind {
177                return h.handle(input);
178            }
179        }
180        None
181    }
182}
183
184// ---------------------------------------------------------------------------
185// first_of
186// ---------------------------------------------------------------------------
187
188/// Try a slice of boxed handlers in order; return the first `Some` result.
189///
190/// # Example
191///
192/// ```rust
193/// use tree_sitter_utils::{first_of, always, never, BoxedHandler, HandlerExt};
194///
195/// let handlers: Vec<BoxedHandler<(), u32>> = vec![
196///     never::<(), u32>().boxed(),
197///     always::<(), u32>(1).boxed(),
198/// ];
199/// let h = first_of(handlers);
200/// let _ = h;
201/// ```
202pub fn first_of<Ctx, R>(
203    handlers: Vec<crate::combinators::boxed::BoxedHandler<Ctx, R>>,
204) -> FirstOf<Ctx, R> {
205    FirstOf { handlers }
206}
207
208/// Handler produced by [`first_of`].
209///
210/// # Example
211///
212/// ```rust
213/// use tree_sitter_utils::first_of;
214/// let h = first_of::<(), u32>(vec![]);
215/// let _ = h;
216/// ```
217pub struct FirstOf<Ctx, R> {
218    handlers: Vec<crate::combinators::boxed::BoxedHandler<Ctx, R>>,
219}
220
221impl<Ctx, R> Handler<Ctx, R> for FirstOf<Ctx, R>
222where
223    Ctx: Copy,
224{
225    fn handle<'tree>(&self, input: Input<'tree, Ctx>) -> HandlerResult<R> {
226        for h in &self.handlers {
227            let result = h.handle(input);
228            if result.is_some() {
229                return result;
230            }
231        }
232        None
233    }
234}