tree-sitter-iter-0.0.3/.cargo_vcs_info.json0000644000000001650000000000100142460ustar { "git": { "sha1": "2942f11dc2eb53b60f7d68c19b71ef04c7c11ed5" }, "path_in_vcs": "crates/tree-sitter-iter" }tree-sitter-iter-0.0.3/Cargo.lock0000644000000133450000000000100122250ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "cc" version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", ] [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "find-msvc-tools" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "indexmap" version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", "hashbrown", ] [[package]] name = "itoa" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "proc-macro2" version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] [[package]] name = "regex" version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "indexmap", "itoa", "memchr", "ryu", "serde", "serde_core", ] [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "streaming-iterator" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" [[package]] name = "syn" version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tree-sitter" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2135256a14d38ef69702cf6afdb6a36805d8914523de06eb4e2756cee08736f2" dependencies = [ "cc", "regex", "regex-syntax", "serde_json", "streaming-iterator", "tree-sitter-language", ] [[package]] name = "tree-sitter-iter" version = "0.0.3" dependencies = [ "tree-sitter", "tree-sitter-yaml", ] [[package]] name = "tree-sitter-language" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8" [[package]] name = "tree-sitter-yaml" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53c223db85f05e34794f065454843b0668ebc15d240ada63e2b5939f43ce7c97" dependencies = [ "cc", "tree-sitter-language", ] [[package]] name = "unicode-ident" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" tree-sitter-iter-0.0.3/Cargo.toml0000644000000023040000000000100122410ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2024" rust-version = "1.88.0" name = "tree-sitter-iter" version = "0.0.3" authors = ["William Woodruff "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "A very simple pre-order iterator for tree-sitter CSTs" homepage = "https://docs.zizmor.sh" readme = "README.md" license = "MIT" resolver = "2" [lib] name = "tree_sitter_iter" path = "src/lib.rs" [dependencies.tree-sitter] version = "0.26.2" [dev-dependencies.tree-sitter-yaml] version = "0.7.2" [lints.clippy] dbg_macro = "warn" needless_lifetimes = "warn" print_stderr = "warn" print_stdout = "warn" todo = "warn" unimplemented = "warn" unwrap_used = "warn" use_debug = "warn" tree-sitter-iter-0.0.3/Cargo.toml.orig000064400000000000000000000006021046102023000157210ustar 00000000000000[package] name = "tree-sitter-iter" description = "A very simple pre-order iterator for tree-sitter CSTs" version = "0.0.3" authors.workspace = true homepage.workspace = true edition.workspace = true license.workspace = true rust-version.workspace = true [dependencies] tree-sitter.workspace = true [dev-dependencies] tree-sitter-yaml = { workspace = true } [lints] workspace = true tree-sitter-iter-0.0.3/README.md000064400000000000000000000034411046102023000143150ustar 00000000000000# tree-sitter-iter [![zizmor](https://img.shields.io/badge/%F0%9F%8C%88-zizmor-white?labelColor=white)](https://zizmor.sh/) [![CI](https://github.com/zizmorcore/zizmor/actions/workflows/ci.yml/badge.svg)](https://github.com/zizmorcore/zizmor/actions/workflows/ci.yml) [![Crates.io](https://img.shields.io/crates/v/tree-sitter-iter)](https://crates.io/crates/tree-sitter-iter) [![docs.rs](https://img.shields.io/docsrs/tree-sitter-iter)](https://docs.rs/tree-sitter-iter) [![GitHub Sponsors](https://img.shields.io/github/sponsors/woodruffw?style=flat&logo=githubsponsors&labelColor=white&color=white)](https://github.com/sponsors/woodruffw) [![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord&logoColor=white)](https://discord.com/invite/PGU3zGZuGG) A very simple pre-order iterator for tree-sitter CSTs. This library is part of [zizmor]. ## Usage Given a `tree_sitter::Tree`, you can create a `TreeIter` to iterate over its nodes in pre-order: ```rust use tree_sitter_iter::TreeIter; let tree: tree_sitter::Tree = parse(); // Your parsing logic here. for node in TreeIter::new(&tree) { println!("Node kind: {}", node.kind()); } ``` `TreeIter` implements the standard `Iterator` trait, meaning that you can use any of the normal iterator combinators. For example, to filter only to nodes of a specific kind: ```rust for node in TreeIter::new(&tree).filter(|n| n.kind() == "call") { // Do something with each "call" node. } ``` `tree-sitter-iter`'s space and time performance is equivalent to a walk of the tree using the `TreeCursor` APIs. In other words, it's exactly the same as using a `TreeCursor` manually, but with a more ergonomic iterator interface. See the [documentation] for more details. [documentation]: https://docs.rs/tree-sitter-iter [zizmor]: https://zizmor.sh tree-sitter-iter-0.0.3/src/lib.rs000064400000000000000000000053641046102023000147470ustar 00000000000000//! A very simple pre-order iterator for tree-sitter CSTs. #![deny(rustdoc::broken_intra_doc_links)] #![deny(missing_docs)] #![allow(clippy::redundant_field_names)] #![forbid(unsafe_code)] use tree_sitter::{Node, Tree, TreeCursor}; /// A pre-order iterator over the nodes of a tree-sitter syntax tree. pub struct TreeIter<'tree> { cursor: Option>, } impl<'tree> TreeIter<'tree> { /// Creates a new `TreeSitterIter` for the given syntax tree. pub fn new(tree: &'tree Tree) -> Self { Self { cursor: Some(tree.root_node().walk()), } } } impl<'tree> Iterator for TreeIter<'tree> { type Item = Node<'tree>; fn next(&mut self) -> Option { let cursor = match &mut self.cursor { Some(cursor) => cursor, None => return None, }; let node = cursor.node(); if cursor.goto_first_child() || cursor.goto_next_sibling() { return Some(node); } loop { if !cursor.goto_parent() { // If we can't go to the parent, the walk will be // complete *after* the current node. self.cursor = None; break; } if cursor.goto_next_sibling() { break; } } Some(node) } } #[cfg(test)] mod tests { #[test] fn test_iter_is_total() { let anchors = r#" jobs: job1: env: &env_vars # Define the anchor on first use NODE_ENV: production DATABASE_URL: ${{ secrets.DATABASE_URL }} steps: - run: echo "Using production settings" job2: env: *env_vars # Reuse the environment variables steps: - run: echo "Same environment variables here" "#; // NOTE(ww): These node counts will probably change if // tree-sitter-yaml changes its node structure. Hopefully // that doesn't happen often. let testcases = &[ ("foo:", 9), ("foo: # comment", 10), ("foo: bar", 12), ("foo: bar # comment", 13), ("foo: []", 13), ("foo: [] # comment", 14), (anchors, 100), ]; for (src, expected_count) in testcases { let mut parser = tree_sitter::Parser::new(); parser .set_language(&tree_sitter_yaml::LANGUAGE.into()) .expect("Error loading YAML grammar"); let tree = parser.parse(src, None).expect("Failed to parse source"); let node_count = tree.root_node().descendant_count(); let iter_count = super::TreeIter::new(&tree).count(); assert_eq!(node_count, *expected_count); assert_eq!(node_count, iter_count); } } }