tree_stump 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91b315adc731ea115495d57d4b6cbc0015ed57bbc57da2efc912db78546f466d
4
- data.tar.gz: 496323196882dc02b34b4e77e7fc84bf91d4fea0d8f52545e843f13ca2a47ca2
3
+ metadata.gz: fbb9e50517f16c70868597bb9e48e4e28f01d5450bfdf45eea3e5753beafbf3a
4
+ data.tar.gz: eb8259cdb0612654c6574ae4fad7cef477850116d2f0c14f977dc2901ac8de33
5
5
  SHA512:
6
- metadata.gz: 21a4ad35fb28d48167ec9196832c8fb4bec7d941adf56666043818db6cf5423fc21d9a14ca54adb6a584e5700bc7305d4f6b04146c6116853a627c247e22bc20
7
- data.tar.gz: 15198290a857e5ca222da0c5d570c0ad753cf53fba444b267850742bd1235c5df7b87c02cb83e20d432afdbeab788547332b2e1cbfb4afdbc85944eeb16a2bf3
6
+ metadata.gz: b464a93c384ef2a1ec0d3186110210253e6fb4899cae8beb98cf6e33e32cef79e08ddf38e35ff51532d1dbe2f95f8912c443590c3fc85ae6374519d4ce1c622f
7
+ data.tar.gz: 2a282c202023dbaab64d84642fb2d95dd741572a6e6c70848a3269fe9063aa8962bf393d0b4294eafd0222475f57c6cecd80f7ec344c01a45b917afaae8229e6
data/Cargo.lock CHANGED
@@ -1,21 +1,21 @@
1
1
  # This file is automatically @generated by Cargo.
2
2
  # It is not intended for manual editing.
3
- version = 3
3
+ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "aho-corasick"
7
- version = "1.1.3"
7
+ version = "1.1.4"
8
8
  source = "registry+https://github.com/rust-lang/crates.io-index"
9
- checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
9
+ checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
10
10
  dependencies = [
11
11
  "memchr",
12
12
  ]
13
13
 
14
14
  [[package]]
15
15
  name = "bindgen"
16
- version = "0.69.4"
16
+ version = "0.69.5"
17
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
18
- checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
18
+ checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
19
19
  dependencies = [
20
20
  "bitflags",
21
21
  "cexpr",
@@ -33,16 +33,17 @@ dependencies = [
33
33
 
34
34
  [[package]]
35
35
  name = "bitflags"
36
- version = "2.6.0"
36
+ version = "2.10.0"
37
37
  source = "registry+https://github.com/rust-lang/crates.io-index"
38
- checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
38
+ checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
39
39
 
40
40
  [[package]]
41
41
  name = "cc"
42
- version = "1.1.15"
42
+ version = "1.2.51"
43
43
  source = "registry+https://github.com/rust-lang/crates.io-index"
44
- checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6"
44
+ checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
45
45
  dependencies = [
46
+ "find-msvc-tools",
46
47
  "shlex",
47
48
  ]
48
49
 
@@ -57,9 +58,9 @@ dependencies = [
57
58
 
58
59
  [[package]]
59
60
  name = "cfg-if"
60
- version = "1.0.0"
61
+ version = "1.0.4"
61
62
  source = "registry+https://github.com/rust-lang/crates.io-index"
62
- checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
63
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
63
64
 
64
65
  [[package]]
65
66
  name = "clang-sys"
@@ -74,15 +75,43 @@ dependencies = [
74
75
 
75
76
  [[package]]
76
77
  name = "either"
77
- version = "1.13.0"
78
+ version = "1.15.0"
78
79
  source = "registry+https://github.com/rust-lang/crates.io-index"
79
- checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
80
+ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
81
+
82
+ [[package]]
83
+ name = "equivalent"
84
+ version = "1.0.2"
85
+ source = "registry+https://github.com/rust-lang/crates.io-index"
86
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
87
+
88
+ [[package]]
89
+ name = "find-msvc-tools"
90
+ version = "0.1.6"
91
+ source = "registry+https://github.com/rust-lang/crates.io-index"
92
+ checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
80
93
 
81
94
  [[package]]
82
95
  name = "glob"
83
- version = "0.3.1"
96
+ version = "0.3.3"
84
97
  source = "registry+https://github.com/rust-lang/crates.io-index"
85
- checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
98
+ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
99
+
100
+ [[package]]
101
+ name = "hashbrown"
102
+ version = "0.16.1"
103
+ source = "registry+https://github.com/rust-lang/crates.io-index"
104
+ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
105
+
106
+ [[package]]
107
+ name = "indexmap"
108
+ version = "2.12.1"
109
+ source = "registry+https://github.com/rust-lang/crates.io-index"
110
+ checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
111
+ dependencies = [
112
+ "equivalent",
113
+ "hashbrown",
114
+ ]
86
115
 
87
116
  [[package]]
88
117
  name = "itertools"
@@ -93,6 +122,12 @@ dependencies = [
93
122
  "either",
94
123
  ]
95
124
 
125
+ [[package]]
126
+ name = "itoa"
127
+ version = "1.0.17"
128
+ source = "registry+https://github.com/rust-lang/crates.io-index"
129
+ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
130
+
96
131
  [[package]]
97
132
  name = "lazy_static"
98
133
  version = "1.5.0"
@@ -107,25 +142,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
107
142
 
108
143
  [[package]]
109
144
  name = "libc"
110
- version = "0.2.158"
145
+ version = "0.2.178"
111
146
  source = "registry+https://github.com/rust-lang/crates.io-index"
112
- checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
147
+ checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
113
148
 
114
149
  [[package]]
115
150
  name = "libloading"
116
- version = "0.8.5"
151
+ version = "0.8.9"
117
152
  source = "registry+https://github.com/rust-lang/crates.io-index"
118
- checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
153
+ checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
119
154
  dependencies = [
120
155
  "cfg-if",
121
- "windows-targets",
156
+ "windows-link",
122
157
  ]
123
158
 
124
159
  [[package]]
125
160
  name = "magnus"
126
- version = "0.7.1"
161
+ version = "0.8.2"
127
162
  source = "registry+https://github.com/rust-lang/crates.io-index"
128
- checksum = "3d87ae53030f3a22e83879e666cb94e58a7bdf31706878a0ba48752994146dab"
163
+ checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
129
164
  dependencies = [
130
165
  "magnus-macros",
131
166
  "rb-sys",
@@ -135,9 +170,9 @@ dependencies = [
135
170
 
136
171
  [[package]]
137
172
  name = "magnus-macros"
138
- version = "0.6.0"
173
+ version = "0.8.0"
139
174
  source = "registry+https://github.com/rust-lang/crates.io-index"
140
- checksum = "5968c820e2960565f647819f5928a42d6e874551cab9d88d75e3e0660d7f71e3"
175
+ checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
141
176
  dependencies = [
142
177
  "proc-macro2",
143
178
  "quote",
@@ -146,9 +181,9 @@ dependencies = [
146
181
 
147
182
  [[package]]
148
183
  name = "memchr"
149
- version = "2.7.4"
184
+ version = "2.7.6"
150
185
  source = "registry+https://github.com/rust-lang/crates.io-index"
151
- checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
186
+ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
152
187
 
153
188
  [[package]]
154
189
  name = "minimal-lexical"
@@ -168,36 +203,36 @@ dependencies = [
168
203
 
169
204
  [[package]]
170
205
  name = "proc-macro2"
171
- version = "1.0.86"
206
+ version = "1.0.104"
172
207
  source = "registry+https://github.com/rust-lang/crates.io-index"
173
- checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
208
+ checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
174
209
  dependencies = [
175
210
  "unicode-ident",
176
211
  ]
177
212
 
178
213
  [[package]]
179
214
  name = "quote"
180
- version = "1.0.37"
215
+ version = "1.0.42"
181
216
  source = "registry+https://github.com/rust-lang/crates.io-index"
182
- checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
217
+ checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
183
218
  dependencies = [
184
219
  "proc-macro2",
185
220
  ]
186
221
 
187
222
  [[package]]
188
223
  name = "rb-sys"
189
- version = "0.9.102"
224
+ version = "0.9.123"
190
225
  source = "registry+https://github.com/rust-lang/crates.io-index"
191
- checksum = "df4dec4b1d304c3b308a2cd86b1216ea45dd4361f4e9fa056f108332d0a450c1"
226
+ checksum = "45fb1a185af97ee456f1c9e56dbe6e2e662bec4fdeaf83c4c28e0e6adfb18816"
192
227
  dependencies = [
193
228
  "rb-sys-build",
194
229
  ]
195
230
 
196
231
  [[package]]
197
232
  name = "rb-sys-build"
198
- version = "0.9.102"
233
+ version = "0.9.123"
199
234
  source = "registry+https://github.com/rust-lang/crates.io-index"
200
- checksum = "1d71de3e29d174b8fb17b5d4470f27d7aa2605f8a9d05fda0d3aeff30e05a570"
235
+ checksum = "a58ebd02d7a6033e6a5f6f8d150c1e9f16506039092b84a73e6bedce6d3adf41"
201
236
  dependencies = [
202
237
  "bindgen",
203
238
  "lazy_static",
@@ -210,15 +245,15 @@ dependencies = [
210
245
 
211
246
  [[package]]
212
247
  name = "rb-sys-env"
213
- version = "0.1.2"
248
+ version = "0.2.2"
214
249
  source = "registry+https://github.com/rust-lang/crates.io-index"
215
- checksum = "a35802679f07360454b418a5d1735c89716bde01d35b1560fc953c1415a0b3bb"
250
+ checksum = "08f8d2924cf136a1315e2b4c7460a39f62ef11ee5d522df9b2750fab55b868b6"
216
251
 
217
252
  [[package]]
218
253
  name = "regex"
219
- version = "1.10.6"
254
+ version = "1.12.2"
220
255
  source = "registry+https://github.com/rust-lang/crates.io-index"
221
- checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
256
+ checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
222
257
  dependencies = [
223
258
  "aho-corasick",
224
259
  "memchr",
@@ -228,9 +263,9 @@ dependencies = [
228
263
 
229
264
  [[package]]
230
265
  name = "regex-automata"
231
- version = "0.4.7"
266
+ version = "0.4.13"
232
267
  source = "registry+https://github.com/rust-lang/crates.io-index"
233
- checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
268
+ checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
234
269
  dependencies = [
235
270
  "aho-corasick",
236
271
  "memchr",
@@ -239,9 +274,9 @@ dependencies = [
239
274
 
240
275
  [[package]]
241
276
  name = "regex-syntax"
242
- version = "0.8.4"
277
+ version = "0.8.8"
243
278
  source = "registry+https://github.com/rust-lang/crates.io-index"
244
- checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
279
+ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
245
280
 
246
281
  [[package]]
247
282
  name = "rustc-hash"
@@ -251,118 +286,128 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
251
286
 
252
287
  [[package]]
253
288
  name = "seq-macro"
254
- version = "0.3.5"
289
+ version = "0.3.6"
255
290
  source = "registry+https://github.com/rust-lang/crates.io-index"
256
- checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4"
291
+ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
257
292
 
258
293
  [[package]]
259
- name = "shell-words"
260
- version = "1.1.0"
294
+ name = "serde"
295
+ version = "1.0.228"
261
296
  source = "registry+https://github.com/rust-lang/crates.io-index"
262
- checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
297
+ checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
298
+ dependencies = [
299
+ "serde_core",
300
+ ]
263
301
 
264
302
  [[package]]
265
- name = "shlex"
266
- version = "1.3.0"
303
+ name = "serde_core"
304
+ version = "1.0.228"
267
305
  source = "registry+https://github.com/rust-lang/crates.io-index"
268
- checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
306
+ checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
307
+ dependencies = [
308
+ "serde_derive",
309
+ ]
269
310
 
270
311
  [[package]]
271
- name = "syn"
272
- version = "2.0.77"
312
+ name = "serde_derive"
313
+ version = "1.0.228"
273
314
  source = "registry+https://github.com/rust-lang/crates.io-index"
274
- checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
315
+ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
275
316
  dependencies = [
276
317
  "proc-macro2",
277
318
  "quote",
278
- "unicode-ident",
319
+ "syn",
279
320
  ]
280
321
 
281
322
  [[package]]
282
- name = "tree-sitter"
283
- version = "0.22.6"
323
+ name = "serde_json"
324
+ version = "1.0.148"
284
325
  source = "registry+https://github.com/rust-lang/crates.io-index"
285
- checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca"
326
+ checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
286
327
  dependencies = [
287
- "cc",
288
- "regex",
289
- ]
290
-
291
- [[package]]
292
- name = "tree_stump"
293
- version = "0.1.0"
294
- dependencies = [
295
- "libloading",
296
- "magnus",
297
- "tree-sitter",
328
+ "indexmap",
329
+ "itoa",
330
+ "memchr",
331
+ "serde",
332
+ "serde_core",
333
+ "zmij",
298
334
  ]
299
335
 
300
336
  [[package]]
301
- name = "unicode-ident"
302
- version = "1.0.12"
337
+ name = "shell-words"
338
+ version = "1.1.1"
303
339
  source = "registry+https://github.com/rust-lang/crates.io-index"
304
- checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
340
+ checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
305
341
 
306
342
  [[package]]
307
- name = "windows-targets"
308
- version = "0.52.6"
343
+ name = "shlex"
344
+ version = "1.3.0"
309
345
  source = "registry+https://github.com/rust-lang/crates.io-index"
310
- checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
311
- dependencies = [
312
- "windows_aarch64_gnullvm",
313
- "windows_aarch64_msvc",
314
- "windows_i686_gnu",
315
- "windows_i686_gnullvm",
316
- "windows_i686_msvc",
317
- "windows_x86_64_gnu",
318
- "windows_x86_64_gnullvm",
319
- "windows_x86_64_msvc",
320
- ]
346
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
321
347
 
322
348
  [[package]]
323
- name = "windows_aarch64_gnullvm"
324
- version = "0.52.6"
349
+ name = "streaming-iterator"
350
+ version = "0.1.9"
325
351
  source = "registry+https://github.com/rust-lang/crates.io-index"
326
- checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
352
+ checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
327
353
 
328
354
  [[package]]
329
- name = "windows_aarch64_msvc"
330
- version = "0.52.6"
355
+ name = "syn"
356
+ version = "2.0.112"
331
357
  source = "registry+https://github.com/rust-lang/crates.io-index"
332
- checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
358
+ checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
359
+ dependencies = [
360
+ "proc-macro2",
361
+ "quote",
362
+ "unicode-ident",
363
+ ]
333
364
 
334
365
  [[package]]
335
- name = "windows_i686_gnu"
336
- version = "0.52.6"
366
+ name = "tree-sitter"
367
+ version = "0.26.3"
337
368
  source = "registry+https://github.com/rust-lang/crates.io-index"
338
- checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
369
+ checksum = "974d205cc395652cfa8b37daa053fe56eebd429acf8dc055503fee648dae981e"
370
+ dependencies = [
371
+ "cc",
372
+ "regex",
373
+ "regex-syntax",
374
+ "serde_json",
375
+ "streaming-iterator",
376
+ "tree-sitter-language",
377
+ ]
339
378
 
340
379
  [[package]]
341
- name = "windows_i686_gnullvm"
342
- version = "0.52.6"
380
+ name = "tree-sitter-language"
381
+ version = "0.1.6"
343
382
  source = "registry+https://github.com/rust-lang/crates.io-index"
344
- checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
383
+ checksum = "4ae62f7eae5eb549c71b76658648b72cc6111f2d87d24a1e31fa907f4943e3ce"
345
384
 
346
385
  [[package]]
347
- name = "windows_i686_msvc"
348
- version = "0.52.6"
349
- source = "registry+https://github.com/rust-lang/crates.io-index"
350
- checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
386
+ name = "tree_stump"
387
+ version = "0.1.0"
388
+ dependencies = [
389
+ "libloading",
390
+ "magnus",
391
+ "rb-sys",
392
+ "streaming-iterator",
393
+ "tree-sitter",
394
+ "tree-sitter-language",
395
+ ]
351
396
 
352
397
  [[package]]
353
- name = "windows_x86_64_gnu"
354
- version = "0.52.6"
398
+ name = "unicode-ident"
399
+ version = "1.0.22"
355
400
  source = "registry+https://github.com/rust-lang/crates.io-index"
356
- checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
401
+ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
357
402
 
358
403
  [[package]]
359
- name = "windows_x86_64_gnullvm"
360
- version = "0.52.6"
404
+ name = "windows-link"
405
+ version = "0.2.1"
361
406
  source = "registry+https://github.com/rust-lang/crates.io-index"
362
- checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
407
+ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
363
408
 
364
409
  [[package]]
365
- name = "windows_x86_64_msvc"
366
- version = "0.52.6"
410
+ name = "zmij"
411
+ version = "1.0.8"
367
412
  source = "registry+https://github.com/rust-lang/crates.io-index"
368
- checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
413
+ checksum = "317f17ff091ac4515f17cc7a190d2769a8c9a96d227de5d64b500b01cda8f2cd"
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tomohiro Hashidate (joker1007)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # TreeStump
2
+
2
3
  [![RSpec](https://github.com/joker1007/tree_stump/actions/workflows/rspec.yml/badge.svg)](https://github.com/joker1007/tree_stump/actions/workflows/rspec.yml)
3
4
 
4
- [tree-sitter](https://github.com/tree-sitter/tree-sitter) binding for Ruby written by Rust.
5
+ [tree-sitter](https://github.com/tree-sitter/tree-sitter) binding for MRI Ruby written by Rust.
5
6
 
6
7
  ## Installation
7
8
 
@@ -13,6 +14,40 @@ If bundler is not being used to manage dependencies, install the gem by executin
13
14
 
14
15
  $ gem install tree_stump
15
16
 
17
+ ## Platform Compatibility
18
+
19
+ tree_stump is a Rust native extension using [magnus](https://github.com/matsadler/magnus) and [rb-sys](https://github.com/oxidize-rb/rb-sys) for Ruby bindings.
20
+
21
+ | Platform | Supported | Notes |
22
+ |----------|-----------|-------|
23
+ | **MRI Ruby** | ✅ Yes | Full support (3.1+) |
24
+ | **JRuby** | ❌ No | JRuby runs on the JVM and cannot load native `.so` extensions |
25
+ | **TruffleRuby** | ❌ No | magnus/rb-sys are incompatible with TruffleRuby's C API emulation |
26
+
27
+ <details>
28
+ <summary>Why JRuby doesn't work</summary>
29
+
30
+ JRuby runs on the Java Virtual Machine and cannot load native C/Rust extensions (`.so` files). The `rb-sys` build system fails during `extconf.rb` because JRuby doesn't provide the platform detection APIs that native extensions require.
31
+
32
+ **Alternative for JRuby**: Use [java-tree-sitter](https://github.com/tree-sitter/java-tree-sitter) / [jtreesitter](https://central.sonatype.com/artifact/io.github.tree-sitter/jtreesitter) directly, or use [TreeHaver](https://github.com/kettle-rb/tree_haver)'s Java backend which wraps it.
33
+
34
+ </details>
35
+
36
+ <details>
37
+ <summary>Why TruffleRuby doesn't work</summary>
38
+
39
+ TruffleRuby implements Ruby on GraalVM, not as a C program. While it has a C API emulation layer (via Sulong/LLVM), this layer doesn't expose all of MRI's internal structures that `magnus` requires:
40
+
41
+ - Missing C API functions: `rb_bug`, `rb_warning`, `rb_gc_writebarrier`, `rb_data_define`, etc.
42
+ - Missing struct fields: `RBasic.flags`, `RBasic.klass`
43
+ - Missing constants: `ruby_rvalue_flags`, `RUBY_ENC_CODERANGE_MASK`
44
+
45
+ These are MRI implementation details that TruffleRuby doesn't need (and can't easily provide) because its objects are implemented completely differently.
46
+
47
+ **Alternative for TruffleRuby**: Use [TreeHaver](https://github.com/kettle-rb/tree_haver) with non-tree-sitter backends (prism, psych, citrus) for parsing needs.
48
+
49
+ </details>
50
+
16
51
  ## Usage
17
52
 
18
53
  ```ruby
@@ -49,12 +84,14 @@ puts tree.root_node.to_sexp
49
84
  ### Requirements
50
85
 
51
86
  - Rust Toolchain
87
+ - MRI Ruby (not JRuby or TruffleRuby)
52
88
  - tree-sitter-ruby
53
89
 
54
90
  1. Download source of tree-sitter-ruby from [GitHub Repository](https://github.com/tree-sitter/tree-sitter-ruby).
55
- 1. Extract tree-sitter-ruby source
56
- 1. mv tree-sitter-ruby-v{version_num} to tree_stump/tree-sitter-ruby
57
- 1. Execute `make` in tree-sitter-ruby directory
91
+ 2. Extract tree-sitter-ruby source
92
+ 3. mv tree-sitter-ruby-v{version_num} to tree_stump/tree-sitter-ruby
93
+ 4. Execute `make` in tree-sitter-ruby directory
94
+ 5. Execute `bundle exec rake compile`
58
95
 
59
96
  ## Contributing
60
97
 
@@ -9,6 +9,9 @@ publish = false
9
9
  crate-type = ["cdylib"]
10
10
 
11
11
  [dependencies]
12
- magnus = { version = "0.7.1" }
13
- tree-sitter = "~0.22"
12
+ magnus = { version = "0.8.2" }
13
+ rb-sys = { version = "0.9.119", features = ["stable-api-compiled-fallback"] }
14
+ tree-sitter = "0.26"
15
+ tree-sitter-language = "0.1"
14
16
  libloading = "~0.8.4"
17
+ streaming-iterator = "0.1"
@@ -8,7 +8,11 @@ unsafe impl Send for LanguageRef<'_> {}
8
8
 
9
9
  impl<'a> LanguageRef<'a> {
10
10
  pub fn version(&self) -> usize {
11
- self.raw_language_ref.version()
11
+ self.raw_language_ref.abi_version()
12
+ }
13
+
14
+ pub fn abi_version(&self) -> usize {
15
+ self.raw_language_ref.abi_version()
12
16
  }
13
17
 
14
18
  pub fn node_kind_count(&self) -> usize {
@@ -1,7 +1,6 @@
1
1
  use magnus::{function, method, prelude::*, typed_data, value::Lazy, Error, RClass, Ruby};
2
2
 
3
3
  use libloading::Library;
4
- use tree_sitter::ffi::TSLanguage;
5
4
 
6
5
  use std::collections::HashMap;
7
6
  use std::sync::Mutex;
@@ -18,15 +17,16 @@ use crate::language::{LanguageRef, LookaheadIterator};
18
17
  use crate::parser::Parser;
19
18
  use crate::query::{Query, QueryCursor, QueryMatch};
20
19
  use crate::tree::{Node, Tree, TreeCursor};
20
+ use crate::util::build_error;
21
21
 
22
22
  pub static LANG_LIBRARIES: OnceLock<Mutex<HashMap<String, Library>>> = OnceLock::new();
23
23
  pub static LANG_LANGUAGES: OnceLock<Mutex<HashMap<String, tree_sitter::Language>>> =
24
24
  OnceLock::new();
25
25
 
26
26
  pub static QUERY_CAPTURE_CLASS: Lazy<RClass> =
27
- Lazy::new(|ruby| ruby.define_struct(None, ("node", "index")).unwrap());
27
+ Lazy::new(|ruby| ruby.define_struct(None, ("node", "index")).expect("Failed to define QueryCapture struct"));
28
28
 
29
- fn register_lang(lang: String, path: String) -> () {
29
+ fn register_lang(lang: String, path: String) -> Result<(), Error> {
30
30
  let func_name = String::from("tree_sitter_") + &lang;
31
31
  let language;
32
32
 
@@ -34,26 +34,42 @@ fn register_lang(lang: String, path: String) -> () {
34
34
  let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
35
35
 
36
36
  unsafe {
37
- let mut libraries = libraries.lock().unwrap();
38
- let lib = libraries.entry(lang.clone()).or_insert_with(|| {
39
- let loaded = Library::new(path).expect("Failed to load library");
40
- loaded
41
- });
37
+ let mut libraries = libraries.lock().map_err(|e| {
38
+ build_error(format!("Failed to acquire library lock: {}", e))
39
+ })?;
40
+ let lib = match libraries.entry(lang.clone()) {
41
+ std::collections::hash_map::Entry::Occupied(e) => e.into_mut(),
42
+ std::collections::hash_map::Entry::Vacant(e) => {
43
+ let loaded = Library::new(&path).map_err(|err| {
44
+ build_error(format!("Failed to load library '{}': {}", path, err))
45
+ })?;
46
+ e.insert(loaded)
47
+ }
48
+ };
42
49
 
43
- let func: libloading::Symbol<unsafe extern "C" fn() -> *const TSLanguage> =
44
- lib.get(func_name.as_bytes()).unwrap();
50
+ // In tree-sitter 0.26+, we use tree_sitter_language::LanguageFn
51
+ let func: libloading::Symbol<tree_sitter_language::LanguageFn> =
52
+ lib.get(func_name.as_bytes()).map_err(|err| {
53
+ build_error(format!("Failed to find symbol '{}': {}", func_name, err))
54
+ })?;
45
55
 
46
- language = tree_sitter::Language::from_raw(func());
56
+ language = tree_sitter::Language::from(*func);
47
57
 
48
- let mut languages = languages.lock().unwrap();
58
+ let mut languages = languages.lock().map_err(|e| {
59
+ build_error(format!("Failed to acquire language lock: {}", e))
60
+ })?;
49
61
  languages.insert(lang.to_string(), language);
50
62
  };
63
+
64
+ Ok(())
51
65
  }
52
66
 
53
- fn available_langs() -> Vec<String> {
67
+ fn available_langs() -> Result<Vec<String>, Error> {
54
68
  let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
55
- let languages = languages.lock().unwrap();
56
- languages.keys().cloned().collect()
69
+ let languages = languages.lock().map_err(|e| {
70
+ build_error(format!("Failed to acquire language lock: {}", e))
71
+ })?;
72
+ Ok(languages.keys().cloned().collect())
57
73
  }
58
74
 
59
75
  #[magnus::init]
@@ -67,8 +83,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
67
83
  parser_class.define_method("set_language", method!(Parser::set_language, 1))?;
68
84
  parser_class.define_method("parse", method!(Parser::parse, 1))?;
69
85
  parser_class.define_method("reset", method!(Parser::reset, 0))?;
70
- parser_class.define_method("timeout_micros", method!(Parser::timeout_micros, 0))?;
71
- parser_class.define_method("set_timeout_micros", method!(Parser::set_timeout_micros, 1))?;
86
+ // NOTE: timeout_micros was removed in tree-sitter 0.26
72
87
  parser_class.define_method("build_query", method!(Parser::build_query, 1))?;
73
88
 
74
89
  let tree_class = namespace.define_class("Tree", ruby.class_object())?;
@@ -107,15 +122,19 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
107
122
  node_class.define_method("eql?", method!(<Node as typed_data::IsEql>::is_eql, 1))?;
108
123
  node_class.define_method("id", method!(Node::id, 0))?;
109
124
  node_class.define_method("kind", method!(Node::kind, 0))?;
125
+ node_class.define_method("type", method!(Node::kind, 0))?; // Alias for compatibility
110
126
  node_class.define_method("kind_id", method!(Node::kind_id, 0))?;
111
127
  node_class.define_method("grammar_id", method!(Node::grammar_id, 0))?;
112
128
  node_class.define_method("grammar_name", method!(Node::grammar_name, 0))?;
113
129
  node_class.define_method("language", method!(Node::language, 0))?;
114
130
  node_class.define_method("is_named?", method!(Node::is_named, 0))?;
131
+ node_class.define_method("named?", method!(Node::is_named, 0))?; // Alias for compatibility
115
132
  node_class.define_method("is_extra?", method!(Node::is_extra, 0))?;
116
133
  node_class.define_method("has_changes?", method!(Node::has_changes, 0))?;
117
134
  node_class.define_method("has_error?", method!(Node::has_error, 0))?;
118
135
  node_class.define_method("is_error?", method!(Node::is_error, 0))?;
136
+ node_class.define_method("is_missing?", method!(Node::is_missing, 0))?;
137
+ node_class.define_method("missing?", method!(Node::is_missing, 0))?; // Alias for compatibility
119
138
  node_class.define_method("parse_state", method!(Node::parse_state, 0))?;
120
139
  node_class.define_method("next_parse_state", method!(Node::next_parse_state, 0))?;
121
140
  node_class.define_method("start_byte", method!(Node::start_byte, 0))?;
@@ -123,7 +142,9 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
123
142
  node_class.define_method("byte_range", method!(Node::byte_range, 0))?;
124
143
  node_class.define_method("range", method!(Node::range, 0))?;
125
144
  node_class.define_method("start_position", method!(Node::start_position, 0))?;
145
+ node_class.define_method("start_point", method!(Node::start_position, 0))?; // Alias for compatibility
126
146
  node_class.define_method("end_position", method!(Node::end_position, 0))?;
147
+ node_class.define_method("end_point", method!(Node::end_position, 0))?; // Alias for compatibility
127
148
  node_class.define_method("child", method!(Node::child, 1))?;
128
149
  node_class.define_method("child_count", method!(Node::child_count, 0))?;
129
150
  node_class.define_method("named_child", method!(Node::named_child, 1))?;
@@ -180,6 +201,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
180
201
 
181
202
  node_class.define_method("to_sexp", method!(Node::to_sexp, 0))?;
182
203
  node_class.define_method("utf8_text", method!(Node::utf8_text, 1))?;
204
+ node_class.define_method("text", method!(Node::utf8_text, 1))?; // Alias for compatibility
183
205
  node_class.define_method("walk", method!(Node::walk, 0))?;
184
206
 
185
207
  node_class.define_method("inspect", method!(Node::inspect, 0))?;
@@ -215,6 +237,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
215
237
 
216
238
  let language_class = namespace.define_class("LanguageRef", ruby.class_object())?;
217
239
  language_class.define_method("version", method!(LanguageRef::version, 0))?;
240
+ language_class.define_method("abi_version", method!(LanguageRef::abi_version, 0))?;
218
241
  language_class.define_method("node_kind_count", method!(LanguageRef::node_kind_count, 0))?;
219
242
  language_class.define_method(
220
243
  "parse_state_count",
@@ -282,7 +305,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
282
305
  )?;
283
306
 
284
307
  Lazy::force(&QUERY_CAPTURE_CLASS, ruby);
285
- let struct_class = Lazy::try_get_inner(&QUERY_CAPTURE_CLASS).unwrap();
308
+ let struct_class = Lazy::try_get_inner(&QUERY_CAPTURE_CLASS)
309
+ .ok_or_else(|| build_error("Failed to get QueryCapture struct class"))?;
286
310
  namespace.const_set("QueryCapture", struct_class)?;
287
311
 
288
312
  let query_match_class = namespace.define_class("QueryMatch", ruby.class_object())?;
@@ -10,23 +10,36 @@ use std::sync::{Arc, Mutex};
10
10
  #[magnus::wrap(class = "TreeStump::Parser")]
11
11
  pub struct Parser {
12
12
  raw_parser: RefCell<tree_sitter::Parser>,
13
+ /// The name of the currently set language, used to look up from the global map
14
+ language_name: RefCell<Option<String>>,
13
15
  }
14
16
 
15
17
  impl Parser {
16
18
  pub fn new() -> Self {
17
19
  Self {
18
20
  raw_parser: RefCell::new(tree_sitter::Parser::new()),
21
+ language_name: RefCell::new(None),
19
22
  }
20
23
  }
21
24
 
22
25
  pub fn set_language(&self, lang: String) -> Result<bool, magnus::Error> {
23
26
  let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
24
- let languages = languages.lock().unwrap();
27
+ let languages = languages.lock().map_err(|e| {
28
+ build_error(format!("Failed to acquire language lock: {}", e))
29
+ })?;
25
30
  let language = languages.get(&lang);
26
31
  match language {
27
32
  Some(language) => {
33
+ // tree-sitter 0.26+ set_language takes impl Into<LanguageRef<'_>>
28
34
  let result = self.raw_parser.borrow_mut().set_language(language);
29
- result.map_or_else(|e| Err(build_error(e.to_string())), |_| Ok(true))
35
+ result.map_or_else(
36
+ |e| Err(build_error(e.to_string())),
37
+ |_| {
38
+ // Store the language name for later lookup
39
+ *self.language_name.borrow_mut() = Some(lang);
40
+ Ok(true)
41
+ },
42
+ )
30
43
  }
31
44
  None => Err(build_error(format!("Language {} is not registered", lang))),
32
45
  }
@@ -45,23 +58,25 @@ impl Parser {
45
58
  self.raw_parser.borrow_mut().reset();
46
59
  }
47
60
 
48
- pub fn timeout_micros(&self) -> u64 {
49
- self.raw_parser.borrow().timeout_micros()
50
- }
61
+ // NOTE: timeout_micros and set_timeout_micros were removed in tree-sitter 0.26
62
+ // The timeout functionality is no longer available in the C/Rust API
51
63
 
52
- pub fn set_timeout_micros(&self, timeout: u64) {
53
- self.raw_parser.borrow_mut().set_timeout_micros(timeout);
54
- }
64
+ pub fn build_query(&self, source: String) -> Result<Query, magnus::Error> {
65
+ let lang_name = self.language_name.borrow();
66
+ let lang_name = lang_name.as_ref().ok_or_else(|| {
67
+ build_error("No language set on parser")
68
+ })?;
55
69
 
56
- fn language(&self) -> Option<tree_sitter::Language> {
57
- self.raw_parser.borrow().language()
58
- }
70
+ let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
71
+ let languages = languages.lock().map_err(|e| {
72
+ build_error(format!("Failed to acquire language lock: {}", e))
73
+ })?;
59
74
 
60
- pub fn build_query(&self, source: String) -> Result<Query, magnus::Error> {
61
- let lang = self.language();
62
- lang.map_or_else(
63
- || Err(build_error("Failed to get language from parser")),
64
- |lang| Query::new(&lang, source),
65
- )
75
+ let language = languages.get(lang_name).ok_or_else(|| {
76
+ build_error(format!("Language {} is no longer registered", lang_name))
77
+ })?;
78
+
79
+ // Clone the language to pass to Query::new
80
+ Query::new(language, source)
66
81
  }
67
82
  }
@@ -7,6 +7,7 @@ use magnus::{
7
7
  value::{InnerRef, Opaque, ReprValue},
8
8
  Class, Error, IntoValue, RArray, RStruct, RTypedData, Ruby, Value,
9
9
  };
10
+ use streaming_iterator::StreamingIterator;
10
11
 
11
12
  use crate::{data::Point, tree::Node, util::build_error, QUERY_CAPTURE_CLASS};
12
13
 
@@ -45,12 +46,14 @@ impl Query {
45
46
  }
46
47
 
47
48
  pub fn capture_quantifiers(&self, index: usize) -> Result<RArray, Error> {
49
+ let ruby = Ruby::get().map_err(|_| {
50
+ build_error("Ruby is not initialized")
51
+ })?;
48
52
  let raw_query = self.raw_query.borrow();
49
53
  let quantifiers = raw_query
50
54
  .capture_quantifiers(index)
51
55
  .iter()
52
- .map(|q| format!("{:?}", q).into_symbol());
53
- let ruby = Ruby::get().expect("Ruby is not initialized");
56
+ .map(|q| format!("{:?}", q).into_symbol_with(&ruby));
54
57
  let array = ruby.ary_from_iter(quantifiers);
55
58
  Ok(array)
56
59
  }
@@ -128,11 +131,12 @@ impl QueryCursor {
128
131
  let mut cursor = rb_self.raw_cursor.borrow_mut();
129
132
  let raw_query = query.raw_query.borrow();
130
133
 
131
- let matches = cursor.matches(&raw_query, node.get_raw_node(), source.as_bytes());
134
+ let mut matches = cursor.matches(&raw_query, node.get_raw_node(), source.as_bytes());
132
135
  let struct_class = QUERY_CAPTURE_CLASS.get_inner_ref_with(ruby);
133
136
  let array = ruby.ary_new();
134
137
 
135
- for m in matches {
138
+ // tree-sitter 0.24+ uses StreamingIterator instead of Iterator
139
+ while let Some(m) = matches.next() {
136
140
  let captures = ruby.ary_new();
137
141
  for c in m.captures {
138
142
  let r_struct = RStruct::from_value(
@@ -153,7 +157,7 @@ impl QueryCursor {
153
157
  } else {
154
158
  Ok(Yield::Enumerator(rb_self.enumeratorize(
155
159
  "matches",
156
- (query, node, source.into_value()),
160
+ (query, node, source.into_value_with(ruby)),
157
161
  )))
158
162
  }
159
163
  }
@@ -184,10 +188,16 @@ impl QueryCursor {
184
188
  let start: Value = range.beg()?;
185
189
  let end: Value = range.end()?;
186
190
 
187
- let start_typed_data = RTypedData::from_value(start).expect("Expected typed data");
191
+ let ruby = Ruby::get().map_err(|_| build_error("Ruby is not initialized"))?;
192
+
193
+ let start_typed_data = RTypedData::from_value(start).ok_or_else(|| {
194
+ Error::new(ruby.exception_type_error(), "Expected typed data for start point")
195
+ })?;
188
196
  let start = start_typed_data.get::<Point>()?;
189
197
 
190
- let end_typed_data = RTypedData::from_value(end).expect("Expected typed data");
198
+ let end_typed_data = RTypedData::from_value(end).ok_or_else(|| {
199
+ Error::new(ruby.exception_type_error(), "Expected typed data for end point")
200
+ })?;
191
201
  let end = end_typed_data.get::<Point>()?;
192
202
 
193
203
  let point_range = start.into_raw()..end.into_raw();
@@ -60,7 +60,7 @@ pub struct TreeCursor<'cursor> {
60
60
  }
61
61
 
62
62
  impl<'cursor> TreeCursor<'cursor> {
63
- pub fn node(&self) -> Node {
63
+ pub fn node(&self) -> Node<'_> {
64
64
  Node {
65
65
  raw_tree: Arc::clone(&self.raw_tree),
66
66
  raw_node: self.raw_cursor.borrow().node(),
@@ -192,6 +192,10 @@ impl<'tree> Node<'tree> {
192
192
  self.raw_node.is_error()
193
193
  }
194
194
 
195
+ pub fn is_missing(&self) -> bool {
196
+ self.raw_node.is_missing()
197
+ }
198
+
195
199
  pub fn parse_state(&self) -> u16 {
196
200
  self.raw_node.parse_state()
197
201
  }
@@ -225,7 +229,8 @@ impl<'tree> Node<'tree> {
225
229
  }
226
230
 
227
231
  pub fn child(&self, index: usize) -> Option<Self> {
228
- self.raw_node.child(index).map(|node| Self {
232
+ let index_u32: u32 = index.try_into().ok()?;
233
+ self.raw_node.child(index_u32).map(|node| Self {
229
234
  raw_tree: Arc::clone(&self.raw_tree),
230
235
  raw_node: node,
231
236
  })
@@ -236,7 +241,8 @@ impl<'tree> Node<'tree> {
236
241
  }
237
242
 
238
243
  pub fn named_child(&self, index: usize) -> Option<Self> {
239
- self.raw_node.named_child(index).map(|node| Self {
244
+ let index_u32: u32 = index.try_into().ok()?;
245
+ self.raw_node.named_child(index_u32).map(|node| Self {
240
246
  raw_tree: Arc::clone(&self.raw_tree),
241
247
  raw_node: node,
242
248
  })
@@ -416,7 +422,7 @@ impl<'tree> Node<'tree> {
416
422
  ) -> Result<Option<Self>, Error> {
417
423
  Ok(self
418
424
  .raw_node
419
- .child_containing_descendant(descendant.raw_node)
425
+ .child_with_descendant(descendant.raw_node)
420
426
  .map(|node| Self {
421
427
  raw_tree: Arc::clone(&self.raw_tree),
422
428
  raw_node: node,
@@ -507,14 +513,14 @@ impl<'tree> Node<'tree> {
507
513
  self.raw_node.to_sexp()
508
514
  }
509
515
 
510
- pub fn utf8_text(&self, source: String) -> String {
516
+ pub fn utf8_text(&self, source: String) -> Result<String, magnus::Error> {
511
517
  self.raw_node
512
518
  .utf8_text(source.as_bytes())
513
- .unwrap()
514
- .to_string()
519
+ .map(|s| s.to_string())
520
+ .map_err(|e| build_error(format!("Failed to get utf8 text: {}", e)))
515
521
  }
516
522
 
517
- pub fn walk(&self) -> TreeCursor {
523
+ pub fn walk(&self) -> TreeCursor<'_> {
518
524
  TreeCursor {
519
525
  raw_tree: Arc::clone(&self.raw_tree),
520
526
  raw_cursor: RefCell::new(self.raw_node.walk()),
@@ -7,13 +7,24 @@ use magnus::{
7
7
  };
8
8
 
9
9
  static ERROR_CLASS: Lazy<ExceptionClass> = Lazy::new(|ruby| {
10
- let ex = ExceptionClass::from_value(ruby.eval("TreeStump::Error").unwrap()).unwrap();
10
+ let ex = ExceptionClass::from_value(
11
+ ruby.eval("TreeStump::Error").expect("TreeStump::Error class not defined")
12
+ ).expect("Failed to convert to ExceptionClass");
11
13
  register_mark_object(ex);
12
14
  ex
13
15
  });
14
16
 
15
17
  pub fn build_error(message: impl Into<Cow<'static, str>>) -> magnus::Error {
16
- let ruby = Ruby::get().expect("Not in Ruby thread");
17
- let error_class = ERROR_CLASS.get_inner_with(&ruby);
18
- magnus::Error::new(error_class, message)
18
+ match Ruby::get() {
19
+ Ok(ruby) => {
20
+ let error_class = ERROR_CLASS.get_inner_with(&ruby);
21
+ magnus::Error::new(error_class, message)
22
+ }
23
+ Err(_) => {
24
+ // Fallback when Ruby isn't initialized - use deprecated function
25
+ // This case should rarely happen in practice
26
+ #[allow(deprecated)]
27
+ magnus::Error::new(magnus::exception::runtime_error(), message)
28
+ }
29
+ }
19
30
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TreeStump
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/tree_stump.rb CHANGED
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "tree_stump/version"
4
+ require_relative "tree_stump/tree_stump"
4
5
 
5
6
  module TreeStump
6
- class Error < StandardError;
7
- def initialize(msg)
8
- super(msg)
9
- end
10
- end
7
+ class Error < StandardError; end
11
8
 
12
9
  class QueryError < Error; end
13
10
  end
14
11
 
15
- require_relative "tree_stump/tree_stump"
metadata CHANGED
@@ -1,15 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tree_stump
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - joker1007
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-09-03 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: rb_sys
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.9.119
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.9.119
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: rspec
15
28
  requirement: !ruby/object:Gem::Requirement
@@ -24,17 +37,18 @@ dependencies:
24
37
  - - ">="
25
38
  - !ruby/object:Gem::Version
26
39
  version: '0'
27
- description: Ruby bindings for Tree-sitter written in Rust
40
+ description: Ruby bindings for Tree-sitter written in Rust using rb_sys and magnus.
28
41
  email:
29
42
  - kakyoin.hierophant@gmail.com
30
43
  executables: []
31
44
  extensions:
32
- - ext/tree_stump/Cargo.toml
45
+ - ext/tree_stump/extconf.rb
33
46
  extra_rdoc_files: []
34
47
  files:
35
48
  - ".rspec"
36
49
  - Cargo.lock
37
50
  - Cargo.toml
51
+ - LICENSE
38
52
  - README.md
39
53
  - Rakefile
40
54
  - ext/tree_stump/Cargo.toml
@@ -50,11 +64,10 @@ files:
50
64
  - lib/tree_stump/version.rb
51
65
  - sig/tree_house.rbs
52
66
  homepage: https://github.com/joker1007/tree_stump
53
- licenses: []
67
+ licenses:
68
+ - MIT
54
69
  metadata:
55
70
  homepage_uri: https://github.com/joker1007/tree_stump
56
- source_code_uri: https://github.com/joker1007/tree_stump
57
- post_install_message:
58
71
  rdoc_options: []
59
72
  require_paths:
60
73
  - lib
@@ -69,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
82
  - !ruby/object:Gem::Version
70
83
  version: 3.3.11
71
84
  requirements: []
72
- rubygems_version: 3.5.11
73
- signing_key:
85
+ rubygems_version: 4.0.0.dev
74
86
  specification_version: 4
75
87
  summary: Ruby bindings for Tree-sitter written in Rust
76
88
  test_files: []