1#![doc = include_str!("./README.md")]
2
3pub mod ffi;
4mod util;
5
6#[cfg(unix)]
7use std::os::unix::io::AsRawFd;
8
9use std::{
10 char, error,
11 ffi::CStr,
12 fmt, hash, iter,
13 marker::PhantomData,
14 mem::MaybeUninit,
15 num::NonZeroU16,
16 ops,
17 os::raw::{c_char, c_void},
18 ptr::{self, NonNull},
19 slice, str,
20 sync::atomic::AtomicUsize,
21 u16,
22};
23
24#[doc(alias = "TREE_SITTER_LANGUAGE_VERSION")]
32pub const LANGUAGE_VERSION: usize = ffi::TREE_SITTER_LANGUAGE_VERSION as usize;
33
34#[doc(alias = "TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION")]
37pub const MIN_COMPATIBLE_LANGUAGE_VERSION: usize =
38 ffi::TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION as usize;
39
40pub const PARSER_HEADER: &'static str = include_str!("../include/tree_sitter/parser.h");
41
42#[doc(alias = "TSLanguage")]
45#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
46#[repr(transparent)]
47pub struct Language(*const ffi::TSLanguage);
48
49#[doc(alias = "TSTree")]
51pub struct Tree(NonNull<ffi::TSTree>);
52
53#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
57pub struct Point {
58 pub row: usize,
59 pub column: usize,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
65pub struct Range {
66 pub start_byte: usize,
67 pub end_byte: usize,
68 pub start_point: Point,
69 pub end_point: Point,
70}
71
72#[derive(Clone, Copy, Debug, PartialEq, Eq)]
74pub struct InputEdit {
75 pub start_byte: usize,
76 pub old_end_byte: usize,
77 pub new_end_byte: usize,
78 pub start_position: Point,
79 pub old_end_position: Point,
80 pub new_end_position: Point,
81}
82
83#[doc(alias = "TSNode")]
85#[derive(Clone, Copy)]
86#[repr(transparent)]
87pub struct Node<'tree>(ffi::TSNode, PhantomData<&'tree ()>);
88
89#[doc(alias = "TSParser")]
91pub struct Parser(NonNull<ffi::TSParser>);
92
93#[doc(alias = "TSLookaheadIterator")]
95pub struct LookaheadIterator(NonNull<ffi::TSLookaheadIterator>);
96struct LookaheadNamesIterator<'a>(&'a mut LookaheadIterator);
97
98#[derive(Debug, PartialEq, Eq)]
100pub enum LogType {
101 Parse,
102 Lex,
103}
104
105type FieldId = NonZeroU16;
106
107type Logger<'a> = Box<dyn FnMut(LogType, &str) + 'a>;
109
110#[doc(alias = "TSTreeCursor")]
112pub struct TreeCursor<'cursor>(ffi::TSTreeCursor, PhantomData<&'cursor ()>);
113
114#[doc(alias = "TSQuery")]
116#[derive(Debug)]
117pub struct Query {
118 ptr: NonNull<ffi::TSQuery>,
119 metadata: QueryMetadata,
120}
121
122#[derive(Debug, Default, Clone)]
123#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
124pub struct SerializableQuery(Vec<u8>, QueryMetadata);
125
126#[derive(Debug, Default, Clone)]
127#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
128pub struct QueryMetadata {
129 capture_names: Box<[String]>,
130 capture_quantifiers: Box<[Box<[CaptureQuantifier]>]>,
131 text_predicates: Box<[Box<[TextPredicateCapture]>]>,
132 property_settings: Box<[Box<[QueryProperty]>]>,
133 property_predicates: Box<[Box<[(QueryProperty, bool)]>]>,
134 general_predicates: Box<[Box<[QueryPredicate]>]>,
135}
136
137#[derive(Debug, PartialEq, Eq, Clone, Copy)]
139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
140pub enum CaptureQuantifier {
141 Zero,
142 ZeroOrOne,
143 ZeroOrMore,
144 One,
145 OneOrMore,
146}
147
148impl From<ffi::TSQuantifier> for CaptureQuantifier {
149 fn from(value: ffi::TSQuantifier) -> Self {
150 match value {
151 ffi::TSQuantifierZero => CaptureQuantifier::Zero,
152 ffi::TSQuantifierZeroOrOne => CaptureQuantifier::ZeroOrOne,
153 ffi::TSQuantifierZeroOrMore => CaptureQuantifier::ZeroOrMore,
154 ffi::TSQuantifierOne => CaptureQuantifier::One,
155 ffi::TSQuantifierOneOrMore => CaptureQuantifier::OneOrMore,
156 _ => panic!("Unrecognized quantifier: {}", value),
157 }
158 }
159}
160
161#[doc(alias = "TSQueryCursor")]
163pub struct QueryCursor {
164 ptr: NonNull<ffi::TSQueryCursor>,
165}
166
167#[derive(Debug, PartialEq, Eq, Clone)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
170pub struct QueryProperty {
171 pub key: Box<str>,
172 pub value: Option<Box<str>>,
173 pub capture_id: Option<usize>,
174}
175
176#[derive(Debug, PartialEq, Eq, Clone)]
177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
178pub enum QueryPredicateArg {
179 Capture(u32),
180 String(Box<str>),
181}
182
183#[derive(Debug, PartialEq, Eq, Clone)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
186pub struct QueryPredicate {
187 pub operator: Box<str>,
188 pub args: Box<[QueryPredicateArg]>,
189}
190
191pub struct QueryMatch<'cursor, 'tree> {
193 pub pattern_index: usize,
194 pub captures: &'cursor [QueryCapture<'tree>],
195 id: u32,
196 cursor: *mut ffi::TSQueryCursor,
197}
198
199pub struct QueryMatches<'query, 'cursor, T: TextProvider<I>, I: AsRef<[u8]>> {
201 ptr: *mut ffi::TSQueryCursor,
202 query: &'query Query,
203 text_provider: T,
204 buffer1: Vec<u8>,
205 buffer2: Vec<u8>,
206 _phantom: PhantomData<(&'cursor (), I)>,
207}
208
209pub struct QueryCaptures<'query, 'cursor, T: TextProvider<I>, I: AsRef<[u8]>> {
211 ptr: *mut ffi::TSQueryCursor,
212 query: &'query Query,
213 text_provider: T,
214 buffer1: Vec<u8>,
215 buffer2: Vec<u8>,
216 _phantom: PhantomData<(&'cursor (), I)>,
217}
218
219pub trait TextProvider<I>
220where
221 I: AsRef<[u8]>,
222{
223 type I: Iterator<Item = I>;
224 fn text(&mut self, node: Node) -> Self::I;
225}
226
227#[derive(Clone, Copy, Debug)]
229#[repr(C)]
230pub struct QueryCapture<'tree> {
231 pub node: Node<'tree>,
232 pub index: u32,
233}
234
235#[derive(Debug, PartialEq, Eq)]
237pub struct LanguageError {
238 version: usize,
239}
240
241#[derive(Debug, PartialEq, Eq)]
243pub enum SerializationError {
244 LanguageError(LanguageError),
245 AllocationError,
246 DeserializationError(QueryError),
247}
248
249#[derive(Debug, PartialEq, Eq)]
251pub struct IncludedRangesError(pub usize);
252
253#[derive(Debug, PartialEq, Eq)]
255pub struct QueryError {
256 pub row: usize,
257 pub column: usize,
258 pub offset: usize,
259 pub message: String,
260 pub kind: QueryErrorKind,
261}
262
263#[derive(Debug, PartialEq, Eq)]
264pub enum QueryErrorKind {
265 Syntax,
266 NodeType,
267 Field,
268 Capture,
269 Predicate,
270 Structure,
271 Language,
272}
273
274#[derive(Debug, Clone)]
275#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
281enum TextPredicateCapture {
282 EqString(u32, Box<str>, bool, bool),
283 EqCapture(u32, u32, bool, bool),
284 MatchString(
285 u32,
286 #[cfg_attr(feature = "serde", serde(with = "serde_regex"))]
287 regex::bytes::Regex,
288 bool, bool
289 ),
290 AnyString(u32, Box<[Box<str>]>, bool),
291}
292
293pub struct LossyUtf8<'a> {
296 bytes: &'a [u8],
297 in_replacement: bool,
298}
299
300impl Language {
301 #[doc(alias = "ts_language_version")]
304 pub fn version(&self) -> usize {
305 unsafe { ffi::ts_language_version(self.0) as usize }
306 }
307
308 #[doc(alias = "ts_language_symbol_count")]
310 pub fn node_kind_count(&self) -> usize {
311 unsafe { ffi::ts_language_symbol_count(self.0) as usize }
312 }
313
314 #[doc(alias = "ts_language_state_count")]
316 pub fn parse_state_count(&self) -> usize {
317 unsafe { ffi::ts_language_state_count(self.0) as usize }
318 }
319
320 #[doc(alias = "ts_language_symbol_name")]
322 pub fn node_kind_for_id(&self, id: u16) -> Option<&'static str> {
323 let ptr = unsafe { ffi::ts_language_symbol_name(self.0, id) };
324 (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
325 }
326
327 #[doc(alias = "ts_language_symbol_for_name")]
329 pub fn id_for_node_kind(&self, kind: &str, named: bool) -> u16 {
330 unsafe {
331 ffi::ts_language_symbol_for_name(
332 self.0,
333 kind.as_bytes().as_ptr() as *const c_char,
334 kind.len() as u32,
335 named,
336 )
337 }
338 }
339
340 pub fn node_kind_is_named(&self, id: u16) -> bool {
343 unsafe { ffi::ts_language_symbol_type(self.0, id) == ffi::TSSymbolTypeRegular }
344 }
345
346 #[doc(alias = "ts_language_symbol_type")]
347 pub fn node_kind_is_visible(&self, id: u16) -> bool {
348 unsafe { ffi::ts_language_symbol_type(self.0, id) <= ffi::TSSymbolTypeAnonymous }
349 }
350
351 #[doc(alias = "ts_language_field_count")]
353 pub fn field_count(&self) -> usize {
354 unsafe { ffi::ts_language_field_count(self.0) as usize }
355 }
356
357 #[doc(alias = "ts_language_field_name_for_id")]
359 pub fn field_name_for_id(&self, field_id: u16) -> Option<&'static str> {
360 let ptr = unsafe { ffi::ts_language_field_name_for_id(self.0, field_id) };
361 (!ptr.is_null()).then(|| unsafe { CStr::from_ptr(ptr) }.to_str().unwrap())
362 }
363
364 #[doc(alias = "ts_language_field_id_for_name")]
366 pub fn field_id_for_name(&self, field_name: impl AsRef<[u8]>) -> Option<FieldId> {
367 let field_name = field_name.as_ref();
368 let id = unsafe {
369 ffi::ts_language_field_id_for_name(
370 self.0,
371 field_name.as_ptr() as *const c_char,
372 field_name.len() as u32,
373 )
374 };
375 FieldId::new(id)
376 }
377
378 #[doc(alias = "ts_language_next_state")]
387 pub fn next_state(&self, state: u16, id: u16) -> u16 {
388 unsafe { ffi::ts_language_next_state(self.0, state, id) }
389 }
390
391 #[doc(alias = "ts_lookahead_iterator_new")]
405 pub fn lookahead_iterator(&self, state: u16) -> Option<LookaheadIterator> {
406 let ptr = unsafe { ffi::ts_lookahead_iterator_new(self.0, state) };
407 (!ptr.is_null()).then(|| unsafe { LookaheadIterator::from_raw(ptr) })
408 }
409}
410
411impl Parser {
412 pub fn new() -> Parser {
414 unsafe {
415 let parser = ffi::ts_parser_new();
416 Parser(NonNull::new_unchecked(parser))
417 }
418 }
419
420 #[doc(alias = "ts_parser_set_language")]
429 pub fn set_language(&mut self, language: Language) -> Result<(), LanguageError> {
430 let version = language.version();
431 if version < MIN_COMPATIBLE_LANGUAGE_VERSION || version > LANGUAGE_VERSION {
432 Err(LanguageError { version })
433 } else {
434 unsafe {
435 ffi::ts_parser_set_language(self.0.as_ptr(), language.0);
436 }
437 Ok(())
438 }
439 }
440
441 #[doc(alias = "ts_parser_language")]
443 pub fn language(&self) -> Option<Language> {
444 let ptr = unsafe { ffi::ts_parser_language(self.0.as_ptr()) };
445 (!ptr.is_null()).then(|| Language(ptr))
446 }
447
448 #[doc(alias = "ts_parser_logger")]
450 pub fn logger(&self) -> Option<&Logger> {
451 let logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
452 unsafe { (logger.payload as *mut Logger).as_ref() }
453 }
454
455 #[doc(alias = "ts_parser_set_logger")]
457 pub fn set_logger(&mut self, logger: Option<Logger>) {
458 let prev_logger = unsafe { ffi::ts_parser_logger(self.0.as_ptr()) };
459 if !prev_logger.payload.is_null() {
460 drop(unsafe { Box::from_raw(prev_logger.payload as *mut Logger) });
461 }
462
463 let c_logger;
464 if let Some(logger) = logger {
465 let container = Box::new(logger);
466
467 unsafe extern "C" fn log(
468 payload: *mut c_void,
469 c_log_type: ffi::TSLogType,
470 c_message: *const c_char,
471 ) {
472 let callback = (payload as *mut Logger).as_mut().unwrap();
473 if let Ok(message) = CStr::from_ptr(c_message).to_str() {
474 let log_type = if c_log_type == ffi::TSLogTypeParse {
475 LogType::Parse
476 } else {
477 LogType::Lex
478 };
479 callback(log_type, message);
480 }
481 }
482
483 let raw_container = Box::into_raw(container);
484
485 c_logger = ffi::TSLogger {
486 payload: raw_container as *mut c_void,
487 log: Some(log),
488 };
489 } else {
490 c_logger = ffi::TSLogger {
491 payload: ptr::null_mut(),
492 log: None,
493 };
494 }
495
496 unsafe { ffi::ts_parser_set_logger(self.0.as_ptr(), c_logger) };
497 }
498
499 #[cfg(unix)]
504 #[doc(alias = "ts_parser_print_dot_graphs")]
505 pub fn print_dot_graphs(&mut self, file: &impl AsRawFd) {
506 let fd = file.as_raw_fd();
507 unsafe { ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), ffi::dup(fd)) }
508 }
509
510 #[doc(alias = "ts_parser_print_dot_graphs")]
512 pub fn stop_printing_dot_graphs(&mut self) {
513 unsafe { ffi::ts_parser_print_dot_graphs(self.0.as_ptr(), -1) }
514 }
515
516 #[doc(alias = "ts_parser_parse")]
530 pub fn parse(&mut self, text: impl AsRef<[u8]>, old_tree: Option<&Tree>) -> Option<Tree> {
531 let bytes = text.as_ref();
532 let len = bytes.len();
533 self.parse_with(
534 &mut |i, _| (i < len).then(|| &bytes[i..]).unwrap_or_default(),
535 old_tree,
536 )
537 }
538
539 pub fn parse_utf16(
548 &mut self,
549 input: impl AsRef<[u16]>,
550 old_tree: Option<&Tree>,
551 ) -> Option<Tree> {
552 let code_points = input.as_ref();
553 let len = code_points.len();
554 self.parse_utf16_with(
555 &mut |i, _| (i < len).then(|| &code_points[i..]).unwrap_or_default(),
556 old_tree,
557 )
558 }
559
560 pub fn parse_with<T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
572 &mut self,
573 callback: &mut F,
574 old_tree: Option<&Tree>,
575 ) -> Option<Tree> {
576 let mut payload: (&mut F, Option<T>) = (callback, None);
582
583 unsafe extern "C" fn read<T: AsRef<[u8]>, F: FnMut(usize, Point) -> T>(
585 payload: *mut c_void,
586 byte_offset: u32,
587 position: ffi::TSPoint,
588 bytes_read: *mut u32,
589 ) -> *const c_char {
590 let (callback, text) = (payload as *mut (&mut F, Option<T>)).as_mut().unwrap();
591 *text = Some(callback(byte_offset as usize, position.into()));
592 let slice = text.as_ref().unwrap().as_ref();
593 *bytes_read = slice.len() as u32;
594 return slice.as_ptr() as *const c_char;
595 }
596
597 let c_input = ffi::TSInput {
598 payload: &mut payload as *mut (&mut F, Option<T>) as *mut c_void,
599 read: Some(read::<T, F>),
600 encoding: ffi::TSInputEncodingUTF8,
601 };
602
603 let c_old_tree = old_tree.map_or(ptr::null_mut(), |t| t.0.as_ptr());
604 unsafe {
605 let c_new_tree = ffi::ts_parser_parse(self.0.as_ptr(), c_old_tree, c_input);
606 NonNull::new(c_new_tree).map(Tree)
607 }
608 }
609
610 pub fn parse_utf16_with<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
622 &mut self,
623 callback: &mut F,
624 old_tree: Option<&Tree>,
625 ) -> Option<Tree> {
626 let mut payload: (&mut F, Option<T>) = (callback, None);
632
633 unsafe extern "C" fn read<T: AsRef<[u16]>, F: FnMut(usize, Point) -> T>(
635 payload: *mut c_void,
636 byte_offset: u32,
637 position: ffi::TSPoint,
638 bytes_read: *mut u32,
639 ) -> *const c_char {
640 let (callback, text) = (payload as *mut (&mut F, Option<T>)).as_mut().unwrap();
641 *text = Some(callback(
642 (byte_offset / 2) as usize,
643 Point {
644 row: position.row as usize,
645 column: position.column as usize / 2,
646 },
647 ));
648 let slice = text.as_ref().unwrap().as_ref();
649 *bytes_read = slice.len() as u32 * 2;
650 slice.as_ptr() as *const c_char
651 }
652
653 let c_input = ffi::TSInput {
654 payload: &mut payload as *mut (&mut F, Option<T>) as *mut c_void,
655 read: Some(read::<T, F>),
656 encoding: ffi::TSInputEncodingUTF16,
657 };
658
659 let c_old_tree = old_tree.map_or(ptr::null_mut(), |t| t.0.as_ptr());
660 unsafe {
661 let c_new_tree = ffi::ts_parser_parse(self.0.as_ptr(), c_old_tree, c_input);
662 NonNull::new(c_new_tree).map(Tree)
663 }
664 }
665
666 #[doc(alias = "ts_parser_reset")]
673 pub fn reset(&mut self) {
674 unsafe { ffi::ts_parser_reset(self.0.as_ptr()) }
675 }
676
677 #[doc(alias = "ts_parser_timeout_micros")]
681 pub fn timeout_micros(&self) -> u64 {
682 unsafe { ffi::ts_parser_timeout_micros(self.0.as_ptr()) }
683 }
684
685 #[doc(alias = "ts_parser_set_timeout_micros")]
691 pub fn set_timeout_micros(&mut self, timeout_micros: u64) {
692 unsafe { ffi::ts_parser_set_timeout_micros(self.0.as_ptr(), timeout_micros) }
693 }
694
695 #[doc(alias = "ts_parser_set_included_ranges")]
712 pub fn set_included_ranges(&mut self, ranges: &[Range]) -> Result<(), IncludedRangesError> {
713 let ts_ranges: Vec<ffi::TSRange> =
714 ranges.iter().cloned().map(|range| range.into()).collect();
715 let result = unsafe {
716 ffi::ts_parser_set_included_ranges(
717 self.0.as_ptr(),
718 ts_ranges.as_ptr(),
719 ts_ranges.len() as u32,
720 )
721 };
722
723 if result {
724 Ok(())
725 } else {
726 let mut prev_end_byte = 0;
727 for (i, range) in ranges.iter().enumerate() {
728 if range.start_byte < prev_end_byte || range.end_byte < range.start_byte {
729 return Err(IncludedRangesError(i));
730 }
731 prev_end_byte = range.end_byte;
732 }
733 Err(IncludedRangesError(0))
734 }
735 }
736
737 #[doc(alias = "ts_parser_cancellation_flag")]
739 pub unsafe fn cancellation_flag(&self) -> Option<&AtomicUsize> {
740 (ffi::ts_parser_cancellation_flag(self.0.as_ptr()) as *const AtomicUsize).as_ref()
741 }
742
743 #[doc(alias = "ts_parser_set_cancellation_flag")]
749 pub unsafe fn set_cancellation_flag(&mut self, flag: Option<&AtomicUsize>) {
750 if let Some(flag) = flag {
751 ffi::ts_parser_set_cancellation_flag(
752 self.0.as_ptr(),
753 flag as *const AtomicUsize as *const usize,
754 );
755 } else {
756 ffi::ts_parser_set_cancellation_flag(self.0.as_ptr(), ptr::null());
757 }
758 }
759}
760
761impl Drop for Parser {
762 fn drop(&mut self) {
763 self.stop_printing_dot_graphs();
764 self.set_logger(None);
765 unsafe { ffi::ts_parser_delete(self.0.as_ptr()) }
766 }
767}
768
769impl Tree {
770 #[doc(alias = "ts_tree_root_node")]
772 pub fn root_node(&self) -> Node {
773 Node::new(unsafe { ffi::ts_tree_root_node(self.0.as_ptr()) }).unwrap()
774 }
775
776 #[doc(alias = "ts_tree_root_node_with_offset")]
779 pub fn root_node_with_offset(&self, offset_bytes: usize, offset_extent: Point) -> Node {
780 Node::new(unsafe {
781 ffi::ts_tree_root_node_with_offset(
782 self.0.as_ptr(),
783 offset_bytes as u32,
784 offset_extent.into(),
785 )
786 })
787 .unwrap()
788 }
789
790 #[doc(alias = "ts_tree_language")]
792 pub fn language(&self) -> Language {
793 Language(unsafe { ffi::ts_tree_language(self.0.as_ptr()) })
794 }
795
796 #[doc(alias = "ts_tree_edit")]
802 pub fn edit(&mut self, edit: &InputEdit) {
803 let edit = edit.into();
804 unsafe { ffi::ts_tree_edit(self.0.as_ptr(), &edit) };
805 }
806
807 pub fn walk(&self) -> TreeCursor {
809 self.root_node().walk()
810 }
811
812 #[doc(alias = "ts_tree_get_changed_ranges")]
820 pub fn changed_ranges(&self, other: &Tree) -> impl ExactSizeIterator<Item = Range> {
821 let mut count = 0u32;
822 unsafe {
823 let ptr = ffi::ts_tree_get_changed_ranges(
824 self.0.as_ptr(),
825 other.0.as_ptr(),
826 &mut count as *mut u32,
827 );
828 util::CBufferIter::new(ptr, count as usize).map(|r| r.into())
829 }
830 }
831
832 pub fn included_ranges(&self) -> Vec<Range> {
834 let mut count = 0u32;
835 unsafe {
836 let ptr = ffi::ts_tree_included_ranges(self.0.as_ptr(), &mut count as *mut u32);
837 let ranges = slice::from_raw_parts(ptr, count as usize);
838 let result = ranges.iter().copied().map(|range| range.into()).collect();
839 (FREE_FN)(ptr as *mut c_void);
840 result
841 }
842 }
843
844 #[cfg(unix)]
848 #[doc(alias = "ts_tree_print_dot_graph")]
849 pub fn print_dot_graph(&self, file: &impl AsRawFd) {
850 let fd = file.as_raw_fd();
851 unsafe { ffi::ts_tree_print_dot_graph(self.0.as_ptr(), fd) }
852 }
853}
854
855impl fmt::Debug for Tree {
856 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
857 write!(f, "{{Tree {:?}}}", self.root_node())
858 }
859}
860
861impl Drop for Tree {
862 fn drop(&mut self) {
863 unsafe { ffi::ts_tree_delete(self.0.as_ptr()) }
864 }
865}
866
867impl Clone for Tree {
868 fn clone(&self) -> Tree {
869 unsafe { Tree(NonNull::new_unchecked(ffi::ts_tree_copy(self.0.as_ptr()))) }
870 }
871}
872
873impl<'tree> Node<'tree> {
874 fn new(node: ffi::TSNode) -> Option<Self> {
875 (!node.id.is_null()).then(|| Node(node, PhantomData))
876 }
877
878 pub fn id(&self) -> usize {
885 self.0.id as usize
886 }
887
888 #[doc(alias = "ts_node_symbol")]
890 pub fn kind_id(&self) -> u16 {
891 unsafe { ffi::ts_node_symbol(self.0) }
892 }
893
894 #[doc(alias = "ts_node_grammar_symbol")]
897 pub fn grammar_id(&self) -> u16 {
898 unsafe { ffi::ts_node_grammar_symbol(self.0) }
899 }
900
901 #[doc(alias = "ts_node_type")]
903 pub fn kind(&self) -> &'static str {
904 unsafe { CStr::from_ptr(ffi::ts_node_type(self.0)) }
905 .to_str()
906 .unwrap()
907 }
908
909 #[doc(alias = "ts_node_grammar_type")]
912 pub fn grammar_name(&self) -> &'static str {
913 unsafe { CStr::from_ptr(ffi::ts_node_grammar_type(self.0)) }
914 .to_str()
915 .unwrap()
916 }
917
918 #[doc(alias = "ts_node_language")]
920 pub fn language(&self) -> Language {
921 Language(unsafe { ffi::ts_node_language(self.0) })
922 }
923
924 #[doc(alias = "ts_node_is_named")]
929 pub fn is_named(&self) -> bool {
930 unsafe { ffi::ts_node_is_named(self.0) }
931 }
932
933 #[doc(alias = "ts_node_is_extra")]
938 pub fn is_extra(&self) -> bool {
939 unsafe { ffi::ts_node_is_extra(self.0) }
940 }
941
942 #[doc(alias = "ts_node_has_changes")]
944 pub fn has_changes(&self) -> bool {
945 unsafe { ffi::ts_node_has_changes(self.0) }
946 }
947
948 #[doc(alias = "ts_node_has_error")]
951 pub fn has_error(&self) -> bool {
952 unsafe { ffi::ts_node_has_error(self.0) }
953 }
954
955 #[doc(alias = "ts_node_is_error")]
960 pub fn is_error(&self) -> bool {
961 unsafe { ffi::ts_node_is_error(self.0) }
962 }
963
964 #[doc(alias = "ts_node_parse_state")]
966 pub fn parse_state(&self) -> u16 {
967 unsafe { ffi::ts_node_parse_state(self.0) }
968 }
969
970 #[doc(alias = "ts_node_next_parse_state")]
972 pub fn next_parse_state(&self) -> u16 {
973 unsafe { ffi::ts_node_next_parse_state(self.0) }
974 }
975
976 #[doc(alias = "ts_node_is_missing")]
981 pub fn is_missing(&self) -> bool {
982 unsafe { ffi::ts_node_is_missing(self.0) }
983 }
984
985 #[doc(alias = "ts_node_start_byte")]
987 pub fn start_byte(&self) -> usize {
988 unsafe { ffi::ts_node_start_byte(self.0) as usize }
989 }
990
991 #[doc(alias = "ts_node_end_byte")]
993 pub fn end_byte(&self) -> usize {
994 unsafe { ffi::ts_node_end_byte(self.0) as usize }
995 }
996
997 pub fn byte_range(&self) -> std::ops::Range<usize> {
999 self.start_byte()..self.end_byte()
1000 }
1001
1002 pub fn range(&self) -> Range {
1005 Range {
1006 start_byte: self.start_byte(),
1007 end_byte: self.end_byte(),
1008 start_point: self.start_position(),
1009 end_point: self.end_position(),
1010 }
1011 }
1012
1013 #[doc(alias = "ts_node_start_point")]
1015 pub fn start_position(&self) -> Point {
1016 let result = unsafe { ffi::ts_node_start_point(self.0) };
1017 result.into()
1018 }
1019
1020 #[doc(alias = "ts_node_end_point")]
1022 pub fn end_position(&self) -> Point {
1023 let result = unsafe { ffi::ts_node_end_point(self.0) };
1024 result.into()
1025 }
1026
1027 #[doc(alias = "ts_node_child")]
1034 pub fn child(&self, i: usize) -> Option<Self> {
1035 Self::new(unsafe { ffi::ts_node_child(self.0, i as u32) })
1036 }
1037
1038 #[doc(alias = "ts_node_child_count")]
1040 pub fn child_count(&self) -> usize {
1041 unsafe { ffi::ts_node_child_count(self.0) as usize }
1042 }
1043
1044 #[doc(alias = "ts_node_named_child")]
1051 pub fn named_child(&self, i: usize) -> Option<Self> {
1052 Self::new(unsafe { ffi::ts_node_named_child(self.0, i as u32) })
1053 }
1054
1055 #[doc(alias = "ts_node_named_child_count")]
1059 pub fn named_child_count(&self) -> usize {
1060 unsafe { ffi::ts_node_named_child_count(self.0) as usize }
1061 }
1062
1063 #[doc(alias = "ts_node_child_by_field_name")]
1068 pub fn child_by_field_name(&self, field_name: impl AsRef<[u8]>) -> Option<Self> {
1069 let field_name = field_name.as_ref();
1070 Self::new(unsafe {
1071 ffi::ts_node_child_by_field_name(
1072 self.0,
1073 field_name.as_ptr() as *const c_char,
1074 field_name.len() as u32,
1075 )
1076 })
1077 }
1078
1079 #[doc(alias = "ts_node_child_by_field_id")]
1084 pub fn child_by_field_id(&self, field_id: u16) -> Option<Self> {
1085 Self::new(unsafe { ffi::ts_node_child_by_field_id(self.0, field_id) })
1086 }
1087
1088 #[doc(alias = "ts_node_field_name_for_child")]
1090 pub fn field_name_for_child(&self, child_index: u32) -> Option<&'static str> {
1091 unsafe {
1092 let ptr = ffi::ts_node_field_name_for_child(self.0, child_index);
1093 (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1094 }
1095 }
1096
1097 pub fn children<'cursor>(
1107 &self,
1108 cursor: &'cursor mut TreeCursor<'tree>,
1109 ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1110 cursor.reset(*self);
1111 cursor.goto_first_child();
1112 (0..self.child_count()).into_iter().map(move |_| {
1113 let result = cursor.node();
1114 cursor.goto_next_sibling();
1115 result
1116 })
1117 }
1118
1119 pub fn named_children<'cursor>(
1123 &self,
1124 cursor: &'cursor mut TreeCursor<'tree>,
1125 ) -> impl ExactSizeIterator<Item = Node<'tree>> + 'cursor {
1126 cursor.reset(*self);
1127 cursor.goto_first_child();
1128 (0..self.named_child_count()).into_iter().map(move |_| {
1129 while !cursor.node().is_named() {
1130 if !cursor.goto_next_sibling() {
1131 break;
1132 }
1133 }
1134 let result = cursor.node();
1135 cursor.goto_next_sibling();
1136 result
1137 })
1138 }
1139
1140 pub fn children_by_field_name<'cursor>(
1144 &self,
1145 field_name: &str,
1146 cursor: &'cursor mut TreeCursor<'tree>,
1147 ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1148 let field_id = self.language().field_id_for_name(field_name);
1149 let mut done = field_id.is_none();
1150 if !done {
1151 cursor.reset(*self);
1152 cursor.goto_first_child();
1153 }
1154 iter::from_fn(move || {
1155 if !done {
1156 while cursor.field_id() != field_id {
1157 if !cursor.goto_next_sibling() {
1158 return None;
1159 }
1160 }
1161 let result = cursor.node();
1162 if !cursor.goto_next_sibling() {
1163 done = true;
1164 }
1165 return Some(result);
1166 }
1167 None
1168 })
1169 }
1170
1171 pub fn children_by_field_id<'cursor>(
1175 &self,
1176 field_id: FieldId,
1177 cursor: &'cursor mut TreeCursor<'tree>,
1178 ) -> impl Iterator<Item = Node<'tree>> + 'cursor {
1179 cursor.reset(*self);
1180 cursor.goto_first_child();
1181 let mut done = false;
1182 iter::from_fn(move || {
1183 if !done {
1184 while cursor.field_id() != Some(field_id) {
1185 if !cursor.goto_next_sibling() {
1186 return None;
1187 }
1188 }
1189 let result = cursor.node();
1190 if !cursor.goto_next_sibling() {
1191 done = true;
1192 }
1193 return Some(result);
1194 }
1195 None
1196 })
1197 }
1198
1199 #[doc(alias = "ts_node_parent")]
1201 pub fn parent(&self) -> Option<Self> {
1202 Self::new(unsafe { ffi::ts_node_parent(self.0) })
1203 }
1204
1205 #[doc(alias = "ts_node_next_sibling")]
1207 pub fn next_sibling(&self) -> Option<Self> {
1208 Self::new(unsafe { ffi::ts_node_next_sibling(self.0) })
1209 }
1210
1211 #[doc(alias = "ts_node_prev_sibling")]
1213 pub fn prev_sibling(&self) -> Option<Self> {
1214 Self::new(unsafe { ffi::ts_node_prev_sibling(self.0) })
1215 }
1216
1217 #[doc(alias = "ts_node_next_named_sibling")]
1219 pub fn next_named_sibling(&self) -> Option<Self> {
1220 Self::new(unsafe { ffi::ts_node_next_named_sibling(self.0) })
1221 }
1222
1223 #[doc(alias = "ts_node_prev_named_sibling")]
1225 pub fn prev_named_sibling(&self) -> Option<Self> {
1226 Self::new(unsafe { ffi::ts_node_prev_named_sibling(self.0) })
1227 }
1228
1229 #[doc(alias = "ts_node_descendant_count")]
1231 pub fn descendant_count(&self) -> usize {
1232 unsafe { ffi::ts_node_descendant_count(self.0) as usize }
1233 }
1234
1235 #[doc(alias = "ts_node_descendant_for_byte_range")]
1237 pub fn descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1238 Self::new(unsafe {
1239 ffi::ts_node_descendant_for_byte_range(self.0, start as u32, end as u32)
1240 })
1241 }
1242
1243 #[doc(alias = "ts_node_named_descendant_for_byte_range")]
1245 pub fn named_descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Self> {
1246 Self::new(unsafe {
1247 ffi::ts_node_named_descendant_for_byte_range(self.0, start as u32, end as u32)
1248 })
1249 }
1250
1251 #[doc(alias = "ts_node_descendant_for_point_range")]
1253 pub fn descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1254 Self::new(unsafe {
1255 ffi::ts_node_descendant_for_point_range(self.0, start.into(), end.into())
1256 })
1257 }
1258
1259 #[doc(alias = "ts_node_named_descendant_for_point_range")]
1261 pub fn named_descendant_for_point_range(&self, start: Point, end: Point) -> Option<Self> {
1262 Self::new(unsafe {
1263 ffi::ts_node_named_descendant_for_point_range(self.0, start.into(), end.into())
1264 })
1265 }
1266
1267 #[doc(alias = "ts_node_string")]
1268 pub fn to_sexp(&self) -> String {
1269 let c_string = unsafe { ffi::ts_node_string(self.0) };
1270 let result = unsafe { CStr::from_ptr(c_string) }
1271 .to_str()
1272 .unwrap()
1273 .to_string();
1274 unsafe { (FREE_FN)(c_string as *mut c_void) };
1275 result
1276 }
1277
1278 pub fn utf8_text<'a>(&self, source: &'a [u8]) -> Result<&'a str, str::Utf8Error> {
1279 str::from_utf8(&source[self.start_byte()..self.end_byte()])
1280 }
1281
1282 pub fn utf16_text<'a>(&self, source: &'a [u16]) -> &'a [u16] {
1283 &source.as_ref()[self.start_byte()..self.end_byte()]
1284 }
1285
1286 #[doc(alias = "ts_tree_cursor_new")]
1288 pub fn walk(&self) -> TreeCursor<'tree> {
1289 TreeCursor(unsafe { ffi::ts_tree_cursor_new(self.0) }, PhantomData)
1290 }
1291
1292 #[doc(alias = "ts_node_edit")]
1300 pub fn edit(&mut self, edit: &InputEdit) {
1301 let edit = edit.into();
1302 unsafe { ffi::ts_node_edit(&mut self.0 as *mut ffi::TSNode, &edit) }
1303 }
1304}
1305
1306impl PartialEq for Node<'_> {
1307 fn eq(&self, other: &Self) -> bool {
1308 self.0.id == other.0.id
1309 }
1310}
1311
1312impl Eq for Node<'_> {}
1313
1314impl hash::Hash for Node<'_> {
1315 fn hash<H: hash::Hasher>(&self, state: &mut H) {
1316 self.0.id.hash(state);
1317 self.0.context[0].hash(state);
1318 self.0.context[1].hash(state);
1319 self.0.context[2].hash(state);
1320 self.0.context[3].hash(state);
1321 }
1322}
1323
1324impl fmt::Debug for Node<'_> {
1325 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1326 write!(
1327 f,
1328 "{{Node {} {} - {}}}",
1329 self.kind(),
1330 self.start_position(),
1331 self.end_position()
1332 )
1333 }
1334}
1335
1336impl<'cursor> TreeCursor<'cursor> {
1337 #[doc(alias = "ts_tree_cursor_current_node")]
1339 pub fn node(&self) -> Node<'cursor> {
1340 Node(
1341 unsafe { ffi::ts_tree_cursor_current_node(&self.0) },
1342 PhantomData,
1343 )
1344 }
1345
1346 #[doc(alias = "ts_tree_cursor_current_field_id")]
1350 pub fn field_id(&self) -> Option<FieldId> {
1351 let id = unsafe { ffi::ts_tree_cursor_current_field_id(&self.0) };
1352 FieldId::new(id)
1353 }
1354
1355 #[doc(alias = "ts_tree_cursor_current_field_name")]
1357 pub fn field_name(&self) -> Option<&'static str> {
1358 unsafe {
1359 let ptr = ffi::ts_tree_cursor_current_field_name(&self.0);
1360 (!ptr.is_null()).then(|| CStr::from_ptr(ptr).to_str().unwrap())
1361 }
1362 }
1363
1364 #[doc(alias = "ts_tree_cursor_current_depth")]
1368 pub fn depth(&self) -> u32 {
1369 unsafe { ffi::ts_tree_cursor_current_depth(&self.0) }
1370 }
1371
1372 #[doc(alias = "ts_tree_cursor_current_descendant_index")]
1375 pub fn descendant_index(&self) -> usize {
1376 unsafe { ffi::ts_tree_cursor_current_descendant_index(&self.0) as usize }
1377 }
1378
1379 #[doc(alias = "ts_tree_cursor_goto_first_child")]
1384 pub fn goto_first_child(&mut self) -> bool {
1385 return unsafe { ffi::ts_tree_cursor_goto_first_child(&mut self.0) };
1386 }
1387
1388 #[doc(alias = "ts_tree_cursor_goto_last_child")]
1397 pub fn goto_last_child(&mut self) -> bool {
1398 return unsafe { ffi::ts_tree_cursor_goto_last_child(&mut self.0) };
1399 }
1400
1401 #[doc(alias = "ts_tree_cursor_goto_parent")]
1406 pub fn goto_parent(&mut self) -> bool {
1407 return unsafe { ffi::ts_tree_cursor_goto_parent(&mut self.0) };
1408 }
1409
1410 #[doc(alias = "ts_tree_cursor_goto_next_sibling")]
1415 pub fn goto_next_sibling(&mut self) -> bool {
1416 return unsafe { ffi::ts_tree_cursor_goto_next_sibling(&mut self.0) };
1417 }
1418
1419 #[doc(alias = "ts_tree_cursor_goto_descendant")]
1423 pub fn goto_descendant(&mut self, descendant_index: usize) {
1424 return unsafe {
1425 ffi::ts_tree_cursor_goto_descendant(&mut self.0, descendant_index as u32)
1426 };
1427 }
1428
1429 #[doc(alias = "ts_tree_cursor_goto_previous_sibling")]
1440 pub fn goto_previous_sibling(&mut self) -> bool {
1441 return unsafe { ffi::ts_tree_cursor_goto_previous_sibling(&mut self.0) };
1442 }
1443
1444 #[doc(alias = "ts_tree_cursor_goto_first_child_for_byte")]
1450 pub fn goto_first_child_for_byte(&mut self, index: usize) -> Option<usize> {
1451 let result =
1452 unsafe { ffi::ts_tree_cursor_goto_first_child_for_byte(&mut self.0, index as u32) };
1453 (result >= 0).then_some(result as usize)
1454 }
1455
1456 #[doc(alias = "ts_tree_cursor_goto_first_child_for_point")]
1462 pub fn goto_first_child_for_point(&mut self, point: Point) -> Option<usize> {
1463 let result =
1464 unsafe { ffi::ts_tree_cursor_goto_first_child_for_point(&mut self.0, point.into()) };
1465 (result >= 0).then_some(result as usize)
1466 }
1467
1468 #[doc(alias = "ts_tree_cursor_reset")]
1470 pub fn reset(&mut self, node: Node<'cursor>) {
1471 unsafe { ffi::ts_tree_cursor_reset(&mut self.0, node.0) };
1472 }
1473
1474 #[doc(alias = "ts_tree_cursor_reset_to")]
1479 pub fn reset_to(&mut self, cursor: TreeCursor<'cursor>) {
1480 unsafe { ffi::ts_tree_cursor_reset_to(&mut self.0, &cursor.0) };
1481 }
1482}
1483
1484impl Clone for TreeCursor<'_> {
1485 fn clone(&self) -> Self {
1486 TreeCursor(unsafe { ffi::ts_tree_cursor_copy(&self.0) }, PhantomData)
1487 }
1488}
1489
1490impl Drop for TreeCursor<'_> {
1491 fn drop(&mut self) {
1492 unsafe { ffi::ts_tree_cursor_delete(&mut self.0) }
1493 }
1494}
1495
1496impl LookaheadIterator {
1497 #[doc(alias = "ts_lookahead_iterator_language")]
1499 pub fn language(&self) -> Language {
1500 Language(unsafe { ffi::ts_lookahead_iterator_language(self.0.as_ptr()) })
1501 }
1502
1503 #[doc(alias = "ts_lookahead_iterator_current_symbol")]
1505 pub fn current_symbol(&self) -> u16 {
1506 unsafe { ffi::ts_lookahead_iterator_current_symbol(self.0.as_ptr()) }
1507 }
1508
1509 #[doc(alias = "ts_lookahead_iterator_current_symbol_name")]
1511 pub fn current_symbol_name(&self) -> &'static str {
1512 unsafe {
1513 CStr::from_ptr(ffi::ts_lookahead_iterator_current_symbol_name(
1514 self.0.as_ptr(),
1515 ))
1516 .to_str()
1517 .unwrap()
1518 }
1519 }
1520
1521 #[doc(alias = "ts_lookahead_iterator_reset")]
1526 pub fn reset(&mut self, language: Language, state: u16) -> bool {
1527 unsafe { ffi::ts_lookahead_iterator_reset(self.0.as_ptr(), language.0, state) }
1528 }
1529
1530 #[doc(alias = "ts_lookahead_iterator_reset_state")]
1535 pub fn reset_state(&mut self, state: u16) -> bool {
1536 unsafe { ffi::ts_lookahead_iterator_reset_state(self.0.as_ptr(), state) }
1537 }
1538
1539 pub fn iter_names(&mut self) -> impl Iterator<Item = &'static str> + '_ {
1541 LookaheadNamesIterator(self)
1542 }
1543}
1544
1545impl Iterator for LookaheadNamesIterator<'_> {
1546 type Item = &'static str;
1547
1548 #[doc(alias = "ts_lookahead_iterator_next")]
1549 fn next(&mut self) -> Option<Self::Item> {
1550 unsafe { ffi::ts_lookahead_iterator_next(self.0 .0.as_ptr()) }
1551 .then(|| self.0.current_symbol_name())
1552 }
1553}
1554
1555impl Iterator for LookaheadIterator {
1556 type Item = u16;
1557
1558 #[doc(alias = "ts_lookahead_iterator_next")]
1559 fn next(&mut self) -> Option<Self::Item> {
1560 unsafe { ffi::ts_lookahead_iterator_next(self.0.as_ptr()) }.then(|| self.current_symbol())
1562 }
1563}
1564
1565impl Drop for LookaheadIterator {
1566 #[doc(alias = "ts_lookahead_iterator_delete")]
1567 fn drop(&mut self) {
1568 unsafe { ffi::ts_lookahead_iterator_delete(self.0.as_ptr()) }
1569 }
1570}
1571
1572impl Query {
1573 pub fn new(language: Language, source: &str) -> Result<Self, QueryError> {
1580 let mut error_offset = 0u32;
1581 let mut error_type: ffi::TSQueryError = 0;
1582 let bytes = source.as_bytes();
1583
1584 let ptr = unsafe {
1586 ffi::ts_query_new(
1587 language.0,
1588 bytes.as_ptr() as *const c_char,
1589 bytes.len() as u32,
1590 &mut error_offset as *mut u32,
1591 &mut error_type as *mut ffi::TSQueryError,
1592 )
1593 };
1594
1595 if ptr.is_null() {
1597 if error_type == ffi::TSQueryErrorLanguage {
1598 return Err(QueryError {
1599 row: 0,
1600 column: 0,
1601 offset: 0,
1602 message: LanguageError {
1603 version: language.version(),
1604 }
1605 .to_string(),
1606 kind: QueryErrorKind::Language,
1607 });
1608 }
1609
1610 let offset = error_offset as usize;
1611 let mut line_start = 0;
1612 let mut row = 0;
1613 let mut line_containing_error = None;
1614 for line in source.split("\n") {
1615 let line_end = line_start + line.len() + 1;
1616 if line_end > offset {
1617 line_containing_error = Some(line);
1618 break;
1619 }
1620 line_start = line_end;
1621 row += 1;
1622 }
1623 let column = offset - line_start;
1624
1625 let kind;
1626 let message;
1627 match error_type {
1628 ffi::TSQueryErrorNodeType | ffi::TSQueryErrorField | ffi::TSQueryErrorCapture => {
1630 let suffix = source.split_at(offset).1;
1631 let end_offset = suffix
1632 .find(|c| !char::is_alphanumeric(c) && c != '_' && c != '-')
1633 .unwrap_or(suffix.len());
1634 message = suffix.split_at(end_offset).0.to_string();
1635 kind = match error_type {
1636 ffi::TSQueryErrorNodeType => QueryErrorKind::NodeType,
1637 ffi::TSQueryErrorField => QueryErrorKind::Field,
1638 ffi::TSQueryErrorCapture => QueryErrorKind::Capture,
1639 _ => unreachable!(),
1640 };
1641 }
1642
1643 _ => {
1645 message = if let Some(line) = line_containing_error {
1646 line.to_string() + "\n" + &" ".repeat(offset - line_start) + "^"
1647 } else {
1648 "Unexpected EOF".to_string()
1649 };
1650 kind = match error_type {
1651 ffi::TSQueryErrorStructure => QueryErrorKind::Structure,
1652 _ => QueryErrorKind::Syntax,
1653 };
1654 }
1655 };
1656
1657 return Err(QueryError {
1658 row,
1659 column,
1660 offset,
1661 kind,
1662 message,
1663 });
1664 }
1665
1666 unsafe { Query::from_raw_parts(ptr, source) }
1667 }
1668
1669 #[doc(hidden)]
1670 unsafe fn from_raw_parts(ptr: *mut ffi::TSQuery, source: &str) -> Result<Self, QueryError> {
1671 let ptr = {
1672 struct TSQueryDrop(*mut ffi::TSQuery);
1673 impl Drop for TSQueryDrop {
1674 fn drop(&mut self) {
1675 unsafe { ffi::ts_query_delete(self.0) }
1676 }
1677 }
1678 TSQueryDrop(ptr)
1679 };
1680
1681 let string_count = unsafe { ffi::ts_query_string_count(ptr.0) };
1682 let capture_count = unsafe { ffi::ts_query_capture_count(ptr.0) };
1683 let pattern_count = unsafe { ffi::ts_query_pattern_count(ptr.0) as usize };
1684
1685 let mut capture_names = Vec::with_capacity(capture_count as usize);
1686 let mut capture_quantifiers_vec = Vec::with_capacity(pattern_count as usize);
1687 let mut text_predicates_vec = Vec::with_capacity(pattern_count);
1688 let mut property_predicates_vec = Vec::with_capacity(pattern_count);
1689 let mut property_settings_vec = Vec::with_capacity(pattern_count);
1690 let mut general_predicates_vec = Vec::with_capacity(pattern_count);
1691
1692 for i in 0..capture_count {
1694 unsafe {
1695 let mut length = 0u32;
1696 let name = ffi::ts_query_capture_name_for_id(ptr.0, i, &mut length as *mut u32)
1697 as *const u8;
1698 let name = slice::from_raw_parts(name, length as usize);
1699 let name = str::from_utf8_unchecked(name);
1700 capture_names.push(name.to_string());
1701 }
1702 }
1703
1704 for i in 0..pattern_count {
1706 let mut capture_quantifiers = Vec::with_capacity(capture_count as usize);
1707 for j in 0..capture_count {
1708 unsafe {
1709 let quantifier = ffi::ts_query_capture_quantifier_for_id(ptr.0, i as u32, j);
1710 capture_quantifiers.push(quantifier.into());
1711 }
1712 }
1713 capture_quantifiers_vec.push(capture_quantifiers.into());
1714 }
1715
1716 let string_values = (0..string_count)
1718 .map(|i| unsafe {
1719 let mut length = 0u32;
1720 let value =
1721 ffi::ts_query_string_value_for_id(ptr.0, i as u32, &mut length as *mut u32)
1722 as *const u8;
1723 let value = slice::from_raw_parts(value, length as usize);
1724 let value = str::from_utf8_unchecked(value);
1725 value
1726 })
1727 .collect::<Vec<_>>();
1728
1729 for i in 0..pattern_count {
1731 let predicate_steps = unsafe {
1732 let mut length = 0u32;
1733 let raw_predicates =
1734 ffi::ts_query_predicates_for_pattern(ptr.0, i as u32, &mut length as *mut u32);
1735 (length > 0)
1736 .then(|| slice::from_raw_parts(raw_predicates, length as usize))
1737 .unwrap_or_default()
1738 };
1739
1740 let byte_offset = unsafe { ffi::ts_query_start_byte_for_pattern(ptr.0, i as u32) };
1741 let row = source
1742 .char_indices()
1743 .take_while(|(i, _)| *i < byte_offset as usize)
1744 .filter(|(_, c)| *c == '\n')
1745 .count();
1746
1747 use ffi::TSQueryPredicateStepType as T;
1748 const TYPE_DONE: T = ffi::TSQueryPredicateStepTypeDone;
1749 const TYPE_CAPTURE: T = ffi::TSQueryPredicateStepTypeCapture;
1750 const TYPE_STRING: T = ffi::TSQueryPredicateStepTypeString;
1751
1752 let mut text_predicates = Vec::new();
1753 let mut property_predicates = Vec::new();
1754 let mut property_settings = Vec::new();
1755 let mut general_predicates = Vec::new();
1756 for p in predicate_steps.split(|s| s.type_ == TYPE_DONE) {
1757 if p.is_empty() {
1758 continue;
1759 }
1760
1761 if p[0].type_ != TYPE_STRING {
1762 return Err(predicate_error(
1763 row,
1764 format!(
1765 "Expected predicate to start with a function name. Got @{}.",
1766 capture_names[p[0].value_id as usize],
1767 ),
1768 ));
1769 }
1770
1771 let operator_name = string_values[p[0].value_id as usize];
1773 match operator_name {
1774 "eq?" | "not-eq?" | "any-eq?" | "any-not-eq?" => {
1775 if p.len() != 3 {
1776 return Err(predicate_error(
1777 row,
1778 format!(
1779 "Wrong number of arguments to #eq? predicate. Expected 2, got {}.",
1780 p.len() - 1
1781 ),
1782 ));
1783 }
1784 if p[1].type_ != TYPE_CAPTURE {
1785 return Err(predicate_error(row, format!(
1786 "First argument to #eq? predicate must be a capture name. Got literal \"{}\".",
1787 string_values[p[1].value_id as usize],
1788 )));
1789 }
1790
1791 let is_positive = operator_name == "eq?" || operator_name == "any-eq?";
1792 let match_all = match operator_name {
1793 "eq?" | "not-eq?" => true,
1794 "any-eq?" | "any-not-eq?" => false,
1795 _ => unreachable!(),
1796 };
1797 text_predicates.push(if p[2].type_ == TYPE_CAPTURE {
1798 TextPredicateCapture::EqCapture(
1799 p[1].value_id,
1800 p[2].value_id,
1801 is_positive,
1802 match_all,
1803 )
1804 } else {
1805 TextPredicateCapture::EqString(
1806 p[1].value_id,
1807 string_values[p[2].value_id as usize].to_string().into(),
1808 is_positive,
1809 match_all,
1810 )
1811 });
1812 }
1813
1814 "match?" | "not-match?" | "any-match?" | "any-not-match?" => {
1815 if p.len() != 3 {
1816 return Err(predicate_error(row, format!(
1817 "Wrong number of arguments to #match? predicate. Expected 2, got {}.",
1818 p.len() - 1
1819 )));
1820 }
1821 if p[1].type_ != TYPE_CAPTURE {
1822 return Err(predicate_error(row, format!(
1823 "First argument to #match? predicate must be a capture name. Got literal \"{}\".",
1824 string_values[p[1].value_id as usize],
1825 )));
1826 }
1827 if p[2].type_ == TYPE_CAPTURE {
1828 return Err(predicate_error(row, format!(
1829 "Second argument to #match? predicate must be a literal. Got capture @{}.",
1830 capture_names[p[2].value_id as usize],
1831 )));
1832 }
1833
1834 let is_positive =
1835 operator_name == "match?" || operator_name == "any-match?";
1836 let match_all = match operator_name {
1837 "match?" | "not-match?" => true,
1838 "any-match?" | "any-not-match?" => false,
1839 _ => unreachable!(),
1840 };
1841 let regex = &string_values[p[2].value_id as usize];
1842 text_predicates.push(TextPredicateCapture::MatchString(
1843 p[1].value_id,
1844 regex::bytes::Regex::new(regex).map_err(|_| {
1845 predicate_error(row, format!("Invalid regex '{}'", regex))
1846 })?,
1847 is_positive,
1848 match_all,
1849 ));
1850 }
1851
1852 "set!" => property_settings.push(Self::parse_property(
1853 row,
1854 &operator_name,
1855 &capture_names,
1856 &string_values,
1857 &p[1..],
1858 )?),
1859
1860 "is?" | "is-not?" => property_predicates.push((
1861 Self::parse_property(
1862 row,
1863 &operator_name,
1864 &capture_names,
1865 &string_values,
1866 &p[1..],
1867 )?,
1868 operator_name == "is?",
1869 )),
1870
1871 "any-of?" | "not-any-of?" => {
1872 if p.len() < 2 {
1873 return Err(predicate_error(row, format!(
1874 "Wrong number of arguments to #any-of? predicate. Expected at least 1, got {}.",
1875 p.len() - 1
1876 )));
1877 }
1878 if p[1].type_ != TYPE_CAPTURE {
1879 return Err(predicate_error(row, format!(
1880 "First argument to #any-of? predicate must be a capture name. Got literal \"{}\".",
1881 string_values[p[1].value_id as usize],
1882 )));
1883 }
1884
1885 let is_positive = operator_name == "any-of?";
1886 let mut values = Vec::new();
1887 for arg in &p[2..] {
1888 if arg.type_ == TYPE_CAPTURE {
1889 return Err(predicate_error(row, format!(
1890 "Arguments to #any-of? predicate must be literals. Got capture @{}.",
1891 capture_names[arg.value_id as usize],
1892 )));
1893 }
1894 values.push(string_values[arg.value_id as usize]);
1895 }
1896 text_predicates.push(TextPredicateCapture::AnyString(
1897 p[1].value_id,
1898 values
1899 .iter()
1900 .map(|x| x.to_string().into())
1901 .collect::<Vec<_>>()
1902 .into(),
1903 is_positive,
1904 ));
1905 }
1906
1907 _ => general_predicates.push(QueryPredicate {
1908 operator: operator_name.to_string().into(),
1909 args: p[1..]
1910 .iter()
1911 .map(|a| {
1912 if a.type_ == TYPE_CAPTURE {
1913 QueryPredicateArg::Capture(a.value_id)
1914 } else {
1915 QueryPredicateArg::String(
1916 string_values[a.value_id as usize].to_string().into(),
1917 )
1918 }
1919 })
1920 .collect(),
1921 }),
1922 }
1923 }
1924
1925 text_predicates_vec.push(text_predicates.into());
1926 property_predicates_vec.push(property_predicates.into());
1927 property_settings_vec.push(property_settings.into());
1928 general_predicates_vec.push(general_predicates.into());
1929 }
1930
1931 let result = Query {
1932 ptr: unsafe { NonNull::new_unchecked(ptr.0) },
1933 metadata: QueryMetadata {
1934 capture_names: capture_names.into(),
1935 capture_quantifiers: capture_quantifiers_vec.into(),
1936 text_predicates: text_predicates_vec.into(),
1937 property_predicates: property_predicates_vec.into(),
1938 property_settings: property_settings_vec.into(),
1939 general_predicates: general_predicates_vec.into(),
1940 },
1941 };
1942
1943 std::mem::forget(ptr);
1944
1945 Ok(result)
1946 }
1947
1948 #[doc(alias = "ts_query_start_byte_for_pattern")]
1950 pub fn start_byte_for_pattern(&self, pattern_index: usize) -> usize {
1951 if pattern_index >= self.text_predicates.len() {
1952 panic!(
1953 "Pattern index is {} but the pattern count is {}",
1954 pattern_index,
1955 self.text_predicates.len(),
1956 );
1957 }
1958 unsafe {
1959 ffi::ts_query_start_byte_for_pattern(self.ptr.as_ptr(), pattern_index as u32) as usize
1960 }
1961 }
1962
1963 #[doc(alias = "ts_query_pattern_count")]
1965 pub fn pattern_count(&self) -> usize {
1966 unsafe { ffi::ts_query_pattern_count(self.ptr.as_ptr()) as usize }
1967 }
1968
1969 pub fn capture_names(&self) -> &[String] {
1971 &self.capture_names
1972 }
1973
1974 pub fn capture_quantifiers(&self, index: usize) -> &[CaptureQuantifier] {
1976 &self.capture_quantifiers[index]
1977 }
1978
1979 pub fn capture_index_for_name(&self, name: &str) -> Option<u32> {
1981 self.capture_names
1982 .iter()
1983 .position(|n| *n == name)
1984 .map(|ix| ix as u32)
1985 }
1986
1987 pub fn property_predicates(&self, index: usize) -> &[(QueryProperty, bool)] {
1991 &self.property_predicates[index]
1992 }
1993
1994 pub fn property_settings(&self, index: usize) -> &[QueryProperty] {
1998 &self.property_settings[index]
1999 }
2000
2001 pub fn general_predicates(&self, index: usize) -> &[QueryPredicate] {
2009 &self.general_predicates[index]
2010 }
2011
2012 #[doc(alias = "ts_query_disable_capture")]
2017 pub fn disable_capture(&mut self, name: &str) {
2018 unsafe {
2019 ffi::ts_query_disable_capture(
2020 self.ptr.as_ptr(),
2021 name.as_bytes().as_ptr() as *const c_char,
2022 name.len() as u32,
2023 );
2024 }
2025 }
2026
2027 #[doc(alias = "ts_query_disable_pattern")]
2032 pub fn disable_pattern(&mut self, index: usize) {
2033 unsafe { ffi::ts_query_disable_pattern(self.ptr.as_ptr(), index as u32) }
2034 }
2035
2036 #[doc(alias = "ts_query_is_pattern_rooted")]
2038 pub fn is_pattern_rooted(&self, index: usize) -> bool {
2039 unsafe { ffi::ts_query_is_pattern_rooted(self.ptr.as_ptr(), index as u32) }
2040 }
2041
2042 #[doc(alias = "ts_query_is_pattern_non_local")]
2044 pub fn is_pattern_non_local(&self, index: usize) -> bool {
2045 unsafe { ffi::ts_query_is_pattern_non_local(self.ptr.as_ptr(), index as u32) }
2046 }
2047
2048 #[doc(alias = "ts_query_is_pattern_guaranteed_at_step")]
2053 pub fn is_pattern_guaranteed_at_step(&self, byte_offset: usize) -> bool {
2054 unsafe {
2055 ffi::ts_query_is_pattern_guaranteed_at_step(self.ptr.as_ptr(), byte_offset as u32)
2056 }
2057 }
2058
2059 fn parse_property(
2060 row: usize,
2061 function_name: &str,
2062 capture_names: &[String],
2063 string_values: &[&str],
2064 args: &[ffi::TSQueryPredicateStep],
2065 ) -> Result<QueryProperty, QueryError> {
2066 if args.len() == 0 || args.len() > 3 {
2067 return Err(predicate_error(
2068 row,
2069 format!(
2070 "Wrong number of arguments to {} predicate. Expected 1 to 3, got {}.",
2071 function_name,
2072 args.len(),
2073 ),
2074 ));
2075 }
2076
2077 let mut capture_id = None;
2078 let mut key = None;
2079 let mut value = None;
2080
2081 for arg in args {
2082 if arg.type_ == ffi::TSQueryPredicateStepTypeCapture {
2083 if capture_id.is_some() {
2084 return Err(predicate_error(
2085 row,
2086 format!(
2087 "Invalid arguments to {} predicate. Unexpected second capture name @{}",
2088 function_name, capture_names[arg.value_id as usize]
2089 ),
2090 ));
2091 }
2092 capture_id = Some(arg.value_id as usize);
2093 } else if key.is_none() {
2094 key = Some(&string_values[arg.value_id as usize]);
2095 } else if value.is_none() {
2096 value = Some(string_values[arg.value_id as usize]);
2097 } else {
2098 return Err(predicate_error(
2099 row,
2100 format!(
2101 "Invalid arguments to {} predicate. Unexpected third argument @{}",
2102 function_name, string_values[arg.value_id as usize]
2103 ),
2104 ));
2105 }
2106 }
2107
2108 if let Some(key) = key {
2109 Ok(QueryProperty::new(key, value, capture_id))
2110 } else {
2111 return Err(predicate_error(
2112 row,
2113 format!(
2114 "Invalid arguments to {} predicate. Missing key argument",
2115 function_name,
2116 ),
2117 ));
2118 }
2119 }
2120
2121 #[doc(alias = "ts_query_serialize")]
2123 pub fn serializable(mut self) -> Result<SerializableQuery, SerializationError> {
2124 let mut size: usize = 0;
2125 let ptr = unsafe { ffi::ts_query_serialize(self.ptr.as_ptr(), &mut size) };
2126 if ptr.is_null() {
2127 Err(SerializationError::AllocationError)
2128 } else {
2129 let slice = unsafe { slice::from_raw_parts(ptr as *const u8, size) };
2130 let vec = slice.to_vec();
2131 unsafe { (FREE_FN)(ptr as *mut c_void) };
2132 let metadata = std::mem::replace(&mut self.metadata, QueryMetadata::default());
2133 Ok(SerializableQuery(vec, metadata))
2134 }
2135 }
2136
2137 #[doc(alias = "ts_query_deserialize")]
2139 pub fn deserialize(
2140 data: SerializableQuery,
2141 language: Language,
2142 ) -> Result<Self, SerializationError> {
2143 let version = language.version();
2144 if version < MIN_COMPATIBLE_LANGUAGE_VERSION || version > LANGUAGE_VERSION {
2145 Err(SerializationError::LanguageError(LanguageError { version }))
2146 } else {
2147 let ptr = unsafe {
2148 let data_ptr = data.0.as_slice().as_ptr() as *const c_char;
2149 ffi::ts_query_deserialize(data_ptr, language.0)
2150 };
2151 if ptr.is_null() {
2152 Err(SerializationError::AllocationError)
2153 } else {
2154 Ok(Query {
2155 ptr: unsafe { NonNull::new_unchecked(ptr) },
2156 metadata: data.1,
2157 })
2158 }
2159 }
2160 }
2161}
2162
2163impl QueryCursor {
2164 #[doc(alias = "ts_query_cursor_new")]
2168 pub fn new() -> Self {
2169 QueryCursor {
2170 ptr: unsafe { NonNull::new_unchecked(ffi::ts_query_cursor_new()) },
2171 }
2172 }
2173
2174 #[doc(alias = "ts_query_cursor_match_limit")]
2176 pub fn match_limit(&self) -> u32 {
2177 unsafe { ffi::ts_query_cursor_match_limit(self.ptr.as_ptr()) }
2178 }
2179
2180 #[doc(alias = "ts_query_cursor_set_match_limit")]
2183 pub fn set_match_limit(&mut self, limit: u32) {
2184 unsafe {
2185 ffi::ts_query_cursor_set_match_limit(self.ptr.as_ptr(), limit);
2186 }
2187 }
2188
2189 #[doc(alias = "ts_query_cursor_did_exceed_match_limit")]
2192 pub fn did_exceed_match_limit(&self) -> bool {
2193 unsafe { ffi::ts_query_cursor_did_exceed_match_limit(self.ptr.as_ptr()) }
2194 }
2195
2196 #[doc(alias = "ts_query_cursor_exec")]
2202 pub fn matches<'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
2203 &mut self,
2204 query: &'query Query,
2205 node: Node<'tree>,
2206 text_provider: T,
2207 ) -> QueryMatches<'query, 'tree, T, I> {
2208 let ptr = self.ptr.as_ptr();
2209 unsafe { ffi::ts_query_cursor_exec(ptr, query.ptr.as_ptr(), node.0) };
2210 QueryMatches {
2211 ptr,
2212 query,
2213 text_provider,
2214 buffer1: Default::default(),
2215 buffer2: Default::default(),
2216 _phantom: PhantomData,
2217 }
2218 }
2219
2220 #[doc(alias = "ts_query_cursor_exec")]
2225 pub fn captures<'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
2226 &mut self,
2227 query: &'query Query,
2228 node: Node<'tree>,
2229 text_provider: T,
2230 ) -> QueryCaptures<'query, 'tree, T, I> {
2231 let ptr = self.ptr.as_ptr();
2232 unsafe { ffi::ts_query_cursor_exec(ptr, query.ptr.as_ptr(), node.0) };
2233 QueryCaptures {
2234 ptr,
2235 query,
2236 text_provider,
2237 buffer1: Default::default(),
2238 buffer2: Default::default(),
2239 _phantom: PhantomData,
2240 }
2241 }
2242
2243 #[doc(alias = "ts_query_cursor_set_byte_range")]
2245 pub fn set_byte_range(&mut self, range: ops::Range<usize>) -> &mut Self {
2246 unsafe {
2247 ffi::ts_query_cursor_set_byte_range(
2248 self.ptr.as_ptr(),
2249 range.start as u32,
2250 range.end as u32,
2251 );
2252 }
2253 self
2254 }
2255
2256 #[doc(alias = "ts_query_cursor_set_point_range")]
2258 pub fn set_point_range(&mut self, range: ops::Range<Point>) -> &mut Self {
2259 unsafe {
2260 ffi::ts_query_cursor_set_point_range(
2261 self.ptr.as_ptr(),
2262 range.start.into(),
2263 range.end.into(),
2264 );
2265 }
2266 self
2267 }
2268
2269 #[doc(alias = "ts_query_cursor_set_max_start_depth")]
2282 pub fn set_max_start_depth(&mut self, max_start_depth: Option<u32>) -> &mut Self {
2283 unsafe {
2284 ffi::ts_query_cursor_set_max_start_depth(
2285 self.ptr.as_ptr(),
2286 max_start_depth.unwrap_or(u32::MAX),
2287 );
2288 }
2289 self
2290 }
2291}
2292
2293impl<'tree> QueryMatch<'_, 'tree> {
2294 pub fn id(&self) -> u32 {
2295 self.id
2296 }
2297
2298 #[doc(alias = "ts_query_cursor_remove_match")]
2299 pub fn remove(self) {
2300 unsafe { ffi::ts_query_cursor_remove_match(self.cursor, self.id) }
2301 }
2302
2303 pub fn nodes_for_capture_index(
2304 &self,
2305 capture_ix: u32,
2306 ) -> impl Iterator<Item = Node<'tree>> + '_ {
2307 self.captures
2308 .iter()
2309 .filter_map(move |capture| (capture.index == capture_ix).then_some(capture.node))
2310 }
2311
2312 fn new(m: ffi::TSQueryMatch, cursor: *mut ffi::TSQueryCursor) -> Self {
2313 QueryMatch {
2314 cursor,
2315 id: m.id,
2316 pattern_index: m.pattern_index as usize,
2317 captures: (m.capture_count > 0)
2318 .then(|| unsafe {
2319 slice::from_raw_parts(
2320 m.captures as *const QueryCapture<'tree>,
2321 m.capture_count as usize,
2322 )
2323 })
2324 .unwrap_or_default(),
2325 }
2326 }
2327
2328 fn satisfies_text_predicates<I: AsRef<[u8]>>(
2329 &self,
2330 query: &Query,
2331 buffer1: &mut Vec<u8>,
2332 buffer2: &mut Vec<u8>,
2333 text_provider: &mut impl TextProvider<I>,
2334 ) -> bool {
2335 struct NodeText<'a, T> {
2336 buffer: &'a mut Vec<u8>,
2337 first_chunk: Option<T>,
2338 }
2339 impl<'a, T: AsRef<[u8]>> NodeText<'a, T> {
2340 fn new(buffer: &'a mut Vec<u8>) -> Self {
2341 Self {
2342 buffer,
2343 first_chunk: None,
2344 }
2345 }
2346
2347 fn get_text(&mut self, chunks: &mut impl Iterator<Item = T>) -> &[u8] {
2348 self.first_chunk = chunks.next();
2349 if let Some(next_chunk) = chunks.next() {
2350 self.buffer.clear();
2351 self.buffer
2352 .extend_from_slice(self.first_chunk.as_ref().unwrap().as_ref());
2353 self.buffer.extend_from_slice(next_chunk.as_ref());
2354 for chunk in chunks {
2355 self.buffer.extend_from_slice(chunk.as_ref());
2356 }
2357 self.buffer.as_slice()
2358 } else if let Some(ref first_chunk) = self.first_chunk {
2359 first_chunk.as_ref()
2360 } else {
2361 Default::default()
2362 }
2363 }
2364 }
2365
2366 let mut node_text1 = NodeText::new(buffer1);
2367 let mut node_text2 = NodeText::new(buffer2);
2368
2369 query.text_predicates[self.pattern_index]
2370 .iter()
2371 .all(|predicate| match predicate {
2372 TextPredicateCapture::EqCapture(i, j, is_positive, match_all_nodes) => {
2373 let mut nodes_1 = self.nodes_for_capture_index(*i);
2374 let mut nodes_2 = self.nodes_for_capture_index(*j);
2375 while let (Some(node1), Some(node2)) = (nodes_1.next(), nodes_2.next()) {
2376 let mut text1 = text_provider.text(node1);
2377 let mut text2 = text_provider.text(node2);
2378 let text1 = node_text1.get_text(&mut text1);
2379 let text2 = node_text2.get_text(&mut text2);
2380 if (text1 == text2) != *is_positive && *match_all_nodes {
2381 return false;
2382 }
2383 if (text1 == text2) == *is_positive && !*match_all_nodes {
2384 return true;
2385 }
2386 }
2387 nodes_1.next().is_none() && nodes_2.next().is_none()
2388 }
2389 TextPredicateCapture::EqString(i, s, is_positive, match_all_nodes) => {
2390 let nodes = self.nodes_for_capture_index(*i);
2391 for node in nodes {
2392 let mut text = text_provider.text(node);
2393 let text = node_text1.get_text(&mut text);
2394 if (text == s.as_bytes()) != *is_positive && *match_all_nodes {
2395 return false;
2396 }
2397 if (text == s.as_bytes()) == *is_positive && !*match_all_nodes {
2398 return true;
2399 }
2400 }
2401 true
2402 }
2403 TextPredicateCapture::MatchString(i, r, is_positive, match_all_nodes) => {
2404 let nodes = self.nodes_for_capture_index(*i);
2405 for node in nodes {
2406 let mut text = text_provider.text(node);
2407 let text = node_text1.get_text(&mut text);
2408 if (r.is_match(text)) != *is_positive && *match_all_nodes {
2409 return false;
2410 }
2411 if (r.is_match(text)) == *is_positive && !*match_all_nodes {
2412 return true;
2413 }
2414 }
2415 true
2416 }
2417 TextPredicateCapture::AnyString(i, v, is_positive) => {
2418 let nodes = self.nodes_for_capture_index(*i);
2419 for node in nodes {
2420 let mut text = text_provider.text(node);
2421 let text = node_text1.get_text(&mut text);
2422 if (v.iter().any(|s| text == s.as_bytes())) != *is_positive {
2423 return false;
2424 }
2425 }
2426 true
2427 }
2428 })
2429 }
2430}
2431
2432impl std::ops::Deref for Query {
2433 type Target = QueryMetadata;
2434
2435 fn deref(&self) -> &Self::Target {
2436 &self.metadata
2437 }
2438}
2439
2440impl std::ops::DerefMut for Query {
2441 fn deref_mut(&mut self) -> &mut Self::Target {
2442 &mut self.metadata
2443 }
2444}
2445
2446impl QueryProperty {
2447 pub fn new(key: &str, value: Option<&str>, capture_id: Option<usize>) -> Self {
2448 QueryProperty {
2449 capture_id,
2450 key: key.to_string().into(),
2451 value: value.map(|s| s.to_string().into()),
2452 }
2453 }
2454}
2455
2456impl<'query, 'tree: 'query, T: TextProvider<I>, I: AsRef<[u8]>> Iterator
2457 for QueryMatches<'query, 'tree, T, I>
2458{
2459 type Item = QueryMatch<'query, 'tree>;
2460
2461 fn next(&mut self) -> Option<Self::Item> {
2462 unsafe {
2463 loop {
2464 let mut m = MaybeUninit::<ffi::TSQueryMatch>::uninit();
2465 if ffi::ts_query_cursor_next_match(self.ptr, m.as_mut_ptr()) {
2466 let result = QueryMatch::new(m.assume_init(), self.ptr);
2467 if result.satisfies_text_predicates(
2468 self.query,
2469 &mut self.buffer1,
2470 &mut self.buffer2,
2471 &mut self.text_provider,
2472 ) {
2473 return Some(result);
2474 }
2475 } else {
2476 return None;
2477 }
2478 }
2479 }
2480 }
2481}
2482
2483impl<'query, 'tree: 'query, T: TextProvider<I>, I: AsRef<[u8]>> Iterator
2484 for QueryCaptures<'query, 'tree, T, I>
2485{
2486 type Item = (QueryMatch<'query, 'tree>, usize);
2487
2488 fn next(&mut self) -> Option<Self::Item> {
2489 unsafe {
2490 loop {
2491 let mut capture_index = 0u32;
2492 let mut m = MaybeUninit::<ffi::TSQueryMatch>::uninit();
2493 if ffi::ts_query_cursor_next_capture(
2494 self.ptr,
2495 m.as_mut_ptr(),
2496 &mut capture_index as *mut u32,
2497 ) {
2498 let result = QueryMatch::new(m.assume_init(), self.ptr);
2499 if result.satisfies_text_predicates(
2500 self.query,
2501 &mut self.buffer1,
2502 &mut self.buffer2,
2503 &mut self.text_provider,
2504 ) {
2505 return Some((result, capture_index as usize));
2506 } else {
2507 result.remove();
2508 }
2509 } else {
2510 return None;
2511 }
2512 }
2513 }
2514 }
2515}
2516
2517impl<T: TextProvider<I>, I: AsRef<[u8]>> QueryMatches<'_, '_, T, I> {
2518 #[doc(alias = "ts_query_cursor_set_byte_range")]
2519 pub fn set_byte_range(&mut self, range: ops::Range<usize>) {
2520 unsafe {
2521 ffi::ts_query_cursor_set_byte_range(self.ptr, range.start as u32, range.end as u32);
2522 }
2523 }
2524
2525 #[doc(alias = "ts_query_cursor_set_point_range")]
2526 pub fn set_point_range(&mut self, range: ops::Range<Point>) {
2527 unsafe {
2528 ffi::ts_query_cursor_set_point_range(self.ptr, range.start.into(), range.end.into());
2529 }
2530 }
2531}
2532
2533impl<T: TextProvider<I>, I: AsRef<[u8]>> QueryCaptures<'_, '_, T, I> {
2534 #[doc(alias = "ts_query_cursor_set_byte_range")]
2535 pub fn set_byte_range(&mut self, range: ops::Range<usize>) {
2536 unsafe {
2537 ffi::ts_query_cursor_set_byte_range(self.ptr, range.start as u32, range.end as u32);
2538 }
2539 }
2540
2541 #[doc(alias = "ts_query_cursor_set_point_range")]
2542 pub fn set_point_range(&mut self, range: ops::Range<Point>) {
2543 unsafe {
2544 ffi::ts_query_cursor_set_point_range(self.ptr, range.start.into(), range.end.into());
2545 }
2546 }
2547}
2548
2549impl fmt::Debug for QueryMatch<'_, '_> {
2550 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2551 write!(
2552 f,
2553 "QueryMatch {{ id: {}, pattern_index: {}, captures: {:?} }}",
2554 self.id, self.pattern_index, self.captures
2555 )
2556 }
2557}
2558
2559impl<F, R, I> TextProvider<I> for F
2560where
2561 F: FnMut(Node) -> R,
2562 R: Iterator<Item = I>,
2563 I: AsRef<[u8]>,
2564{
2565 type I = R;
2566
2567 fn text(&mut self, node: Node) -> Self::I {
2568 (self)(node)
2569 }
2570}
2571
2572impl<'a> TextProvider<&'a [u8]> for &'a [u8] {
2573 type I = iter::Once<&'a [u8]>;
2574
2575 fn text(&mut self, node: Node) -> Self::I {
2576 iter::once(&self[node.byte_range()])
2577 }
2578}
2579
2580impl PartialEq for Query {
2581 fn eq(&self, other: &Self) -> bool {
2582 self.ptr == other.ptr
2583 }
2584}
2585
2586impl Drop for Query {
2587 fn drop(&mut self) {
2588 unsafe { ffi::ts_query_delete(self.ptr.as_ptr()) }
2589 }
2590}
2591
2592impl Drop for QueryCursor {
2593 fn drop(&mut self) {
2594 unsafe { ffi::ts_query_cursor_delete(self.ptr.as_ptr()) }
2595 }
2596}
2597
2598impl Point {
2599 pub fn new(row: usize, column: usize) -> Self {
2600 Point { row, column }
2601 }
2602}
2603
2604impl fmt::Display for Point {
2605 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
2606 write!(f, "({}, {})", self.row, self.column)
2607 }
2608}
2609
2610impl Into<ffi::TSPoint> for Point {
2611 fn into(self) -> ffi::TSPoint {
2612 ffi::TSPoint {
2613 row: self.row as u32,
2614 column: self.column as u32,
2615 }
2616 }
2617}
2618
2619impl From<ffi::TSPoint> for Point {
2620 fn from(point: ffi::TSPoint) -> Self {
2621 Self {
2622 row: point.row as usize,
2623 column: point.column as usize,
2624 }
2625 }
2626}
2627
2628impl Into<ffi::TSRange> for Range {
2629 fn into(self) -> ffi::TSRange {
2630 ffi::TSRange {
2631 start_byte: self.start_byte as u32,
2632 end_byte: self.end_byte as u32,
2633 start_point: self.start_point.into(),
2634 end_point: self.end_point.into(),
2635 }
2636 }
2637}
2638
2639impl From<ffi::TSRange> for Range {
2640 fn from(range: ffi::TSRange) -> Self {
2641 Self {
2642 start_byte: range.start_byte as usize,
2643 end_byte: range.end_byte as usize,
2644 start_point: range.start_point.into(),
2645 end_point: range.end_point.into(),
2646 }
2647 }
2648}
2649
2650impl Into<ffi::TSInputEdit> for &'_ InputEdit {
2651 fn into(self) -> ffi::TSInputEdit {
2652 ffi::TSInputEdit {
2653 start_byte: self.start_byte as u32,
2654 old_end_byte: self.old_end_byte as u32,
2655 new_end_byte: self.new_end_byte as u32,
2656 start_point: self.start_position.into(),
2657 old_end_point: self.old_end_position.into(),
2658 new_end_point: self.new_end_position.into(),
2659 }
2660 }
2661}
2662
2663impl<'a> LossyUtf8<'a> {
2664 pub fn new(bytes: &'a [u8]) -> Self {
2665 LossyUtf8 {
2666 bytes,
2667 in_replacement: false,
2668 }
2669 }
2670}
2671
2672impl<'a> Iterator for LossyUtf8<'a> {
2673 type Item = &'a str;
2674
2675 fn next(&mut self) -> Option<&'a str> {
2676 if self.bytes.is_empty() {
2677 return None;
2678 }
2679 if self.in_replacement {
2680 self.in_replacement = false;
2681 return Some("\u{fffd}");
2682 }
2683 match std::str::from_utf8(self.bytes) {
2684 Ok(valid) => {
2685 self.bytes = Default::default();
2686 Some(valid)
2687 }
2688 Err(error) => {
2689 if let Some(error_len) = error.error_len() {
2690 let error_start = error.valid_up_to();
2691 if error_start > 0 {
2692 let result =
2693 unsafe { std::str::from_utf8_unchecked(&self.bytes[..error_start]) };
2694 self.bytes = &self.bytes[(error_start + error_len)..];
2695 self.in_replacement = true;
2696 Some(result)
2697 } else {
2698 self.bytes = &self.bytes[error_len..];
2699 Some("\u{fffd}")
2700 }
2701 } else {
2702 None
2703 }
2704 }
2705 }
2706 }
2707}
2708
2709fn predicate_error(row: usize, message: String) -> QueryError {
2710 QueryError {
2711 kind: QueryErrorKind::Predicate,
2712 row,
2713 column: 0,
2714 offset: 0,
2715 message,
2716 }
2717}
2718
2719impl fmt::Display for IncludedRangesError {
2720 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2721 write!(f, "Incorrect range by index: {}", self.0)
2722 }
2723}
2724
2725impl fmt::Display for LanguageError {
2726 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2727 write!(
2728 f,
2729 "Incompatible language version {}. Expected minimum {}, maximum {}",
2730 self.version, MIN_COMPATIBLE_LANGUAGE_VERSION, LANGUAGE_VERSION,
2731 )
2732 }
2733}
2734
2735impl fmt::Display for QueryError {
2736 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2737 let msg = match self.kind {
2738 QueryErrorKind::Field => "Invalid field name ",
2739 QueryErrorKind::NodeType => "Invalid node type ",
2740 QueryErrorKind::Capture => "Invalid capture name ",
2741 QueryErrorKind::Predicate => "Invalid predicate: ",
2742 QueryErrorKind::Structure => "Impossible pattern:\n",
2743 QueryErrorKind::Syntax => "Invalid syntax:\n",
2744 QueryErrorKind::Language => "",
2745 };
2746 if msg.len() > 0 {
2747 write!(
2748 f,
2749 "Query error at {}:{}. {}{}",
2750 self.row + 1,
2751 self.column + 1,
2752 msg,
2753 self.message
2754 )
2755 } else {
2756 write!(f, "{}", self.message)
2757 }
2758 }
2759}
2760
2761extern "C" {
2762 fn free(ptr: *mut c_void);
2763}
2764
2765static mut FREE_FN: unsafe extern "C" fn(ptr: *mut c_void) = free;
2766
2767#[doc(alias = "ts_set_allocator")]
2768pub unsafe fn set_allocator(
2769 new_malloc: Option<unsafe extern "C" fn(usize) -> *mut c_void>,
2770 new_calloc: Option<unsafe extern "C" fn(usize, usize) -> *mut c_void>,
2771 new_realloc: Option<unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void>,
2772 new_free: Option<unsafe extern "C" fn(*mut c_void)>,
2773) {
2774 FREE_FN = new_free.unwrap_or(free);
2775 ffi::ts_set_allocator(new_malloc, new_calloc, new_realloc, new_free);
2776}
2777
2778impl error::Error for IncludedRangesError {}
2779impl error::Error for LanguageError {}
2780impl error::Error for QueryError {}
2781
2782unsafe impl Send for Language {}
2783unsafe impl Sync for Language {}
2784
2785unsafe impl Send for Node<'_> {}
2786unsafe impl Sync for Node<'_> {}
2787
2788unsafe impl Send for LookaheadIterator {}
2789unsafe impl Sync for LookaheadIterator {}
2790
2791unsafe impl Send for LookaheadNamesIterator<'_> {}
2792unsafe impl Sync for LookaheadNamesIterator<'_> {}
2793
2794unsafe impl Send for Parser {}
2795unsafe impl Sync for Parser {}
2796
2797unsafe impl Send for Query {}
2798unsafe impl Sync for Query {}
2799
2800unsafe impl Send for QueryCursor {}
2801unsafe impl Sync for QueryCursor {}
2802
2803unsafe impl Send for Tree {}
2804unsafe impl Sync for Tree {}
2805
2806unsafe impl Send for TreeCursor<'_> {}
2807unsafe impl Sync for TreeCursor<'_> {}