tree_sitter_utils/lib.rs
1//! # tree-sitter-utils
2//!
3//! A composable, parser-combinator-style abstraction over tree-sitter node
4//! dispatch. Instead of writing ad-hoc `match node.kind() { ... }` loops,
5//! you build a chain of typed, zero-cost [`Handler`] combinators that express
6//! "how to map a syntax-tree node (plus arbitrary context) to an output value".
7//!
8//! The crate is fully language-agnostic. All grammar knowledge lives in the
9//! consumer crate.
10//!
11//! ## Quick example
12//!
13//! ```rust
14//! use tree_sitter_utils::{Input, handler_fn, HandlerExt};
15//!
16//! // A minimal handler that labels identifier nodes.
17//! let h = handler_fn(|input: Input<()>| format!("node:{}", input.node.kind()))
18//! .for_kinds(&["identifier", "type_identifier"])
19//! .map(|s| s.to_uppercase());
20//! # let _ = h;
21//! ```
22
23pub mod input;
24pub mod handler;
25pub mod predicates;
26pub mod combinators;
27pub mod constructors;
28pub mod traversal;
29pub mod query;
30
31#[cfg(test)]
32mod tests;
33
34pub use input::Input;
35pub use handler::{Handler, HandlerResult};
36pub use predicates::{NodePredicate, kind_is, kind_is_not, has_parent_kind, node_depth_lte};
37pub use predicates::{has_ancestor_kind, HasAncestorKind};
38pub use predicates::{has_ancestor_kinds, HasAncestorKinds};
39pub use combinators::HandlerExt;
40pub use combinators::boxed::BoxedHandler;
41pub use combinators::find_ancestor::FindAncestor;
42pub use combinators::for_children::{ForChildren, ScanChildren};
43pub use constructors::{handler_fn, dispatch_on_kind, never, always, first_of};