comfit_core/backend.rs
1//! Parser adapters and query matches for the highlighting engine.
2
3use std::ops::Range;
4
5use crate::Error;
6
7pub use crate::query::{Argument, Metadata, Pattern, Predicate, Property, Query};
8
9/// A parser adapter that reports UTF-8 byte ranges and keeps query matches intact.
10pub trait Backend {
11 /// A grammar accepted by the parsing runtime.
12 type Language;
13 /// A compiled runtime query.
14 type Query;
15 /// A parsed tree with node IDs unique within that tree.
16 type Tree;
17
18 /// Compile a query and convert its pattern metadata to the shared format.
19 ///
20 /// # Errors
21 ///
22 /// Return an error for invalid query syntax or unsupported predicates or properties.
23 fn compile(
24 &mut self,
25 language: &Self::Language,
26 source: &str,
27 ) -> Result<Query<Self::Query>, Error>;
28
29 /// Parse the source using the given included UTF-8 byte ranges.
30 ///
31 /// Included ranges preserve source coordinates rather than concatenating text.
32 ///
33 /// # Errors
34 ///
35 /// Return an error when the runtime rejects the language, ranges, or parse.
36 fn parse(
37 &mut self,
38 language: &Self::Language,
39 source: &str,
40 ranges: &[Range<usize>],
41 ) -> Result<Self::Tree, Error>;
42
43 /// Parse using an edited previous tree when supported by this backend.
44 /// The default implementation performs a full parse and drops the old tree.
45 fn parse_incremental(
46 &mut self,
47 language: &Self::Language,
48 source: &str,
49 ranges: &[Range<usize>],
50 _previous: Option<Self::Tree>,
51 _edit: Option<&crate::document::Edit>,
52 ) -> Result<Self::Tree, Error> {
53 self.parse(language, source, ranges)
54 }
55
56 /// Prepare source coordinates for reuse across parses of the same source version.
57 ///
58 /// Call again whenever the source changes, including same-length edits.
59 /// Backends that need no preparation can use the default implementation.
60 ///
61 /// # Errors
62 ///
63 /// Returns an error if the source cannot be represented by the runtime.
64 fn prepare_source(&mut self, _source: &str) -> Result<(), Error> {
65 Ok(())
66 }
67
68 /// Parse a layer after calling [`Self::prepare_source`] for the same source version.
69 ///
70 /// The default implementation delegates to [`Self::parse_incremental`].
71 ///
72 /// # Errors
73 ///
74 /// Returns an error when the runtime rejects the source, language, or ranges.
75 fn parse_prepared(
76 &mut self,
77 language: &Self::Language,
78 source: &str,
79 ranges: &[Range<usize>],
80 previous: Option<Self::Tree>,
81 edit: Option<&crate::document::Edit>,
82 ) -> Result<Self::Tree, Error> {
83 self.parse_incremental(language, source, ranges, previous, edit)
84 }
85
86 /// Collect complete query matches in runtime order, using UTF-8 byte ranges.
87 ///
88 /// Pattern and capture indices must refer to the supplied query. Built-in text
89 /// predicates are evaluated by the runtime. Custom predicates are evaluated by
90 /// [`Query::filtered`].
91 ///
92 /// # Errors
93 ///
94 /// Return an error for runtime failures, invalid coordinates, or match limits.
95 fn matches(
96 &mut self,
97 query: &Query<Self::Query>,
98 tree: &Self::Tree,
99 source: &str,
100 ) -> Result<Vec<Match>, Error>;
101}
102
103/// A query match that preserves relationships between captures.
104#[derive(Clone)]
105pub struct Match {
106 /// Index into [`Query::patterns`].
107 pub pattern: usize,
108 /// Captures in runtime order.
109 pub captures: Vec<Capture>,
110}
111
112/// One captured node and its query capture index.
113#[derive(Clone)]
114pub struct Capture {
115 /// Index into [`Query::capture_names`].
116 pub index: u32,
117 /// Node metadata owned by the highlighting engine.
118 pub node: Node,
119}
120
121/// Node metadata shared by parser adapters, using UTF-8 byte offsets.
122#[derive(Clone)]
123pub struct Node {
124 /// IDs are unique within one parsed tree, not across injection layers.
125 pub id: usize,
126 /// Parent node ID within the same tree, populated when requested by the query.
127 pub parent: Option<usize>,
128 /// Half-open UTF-8 byte range in the original source.
129 pub range: Range<usize>,
130 /// Immediate children in source order.
131 pub children: Vec<Child>,
132 /// Ancestor node kinds, nearest first, for structural query predicates.
133 pub ancestors: Vec<String>,
134 /// Numeric ancestor depth, populated when requested by the query.
135 pub depth: usize,
136}
137
138/// An immediate child used to exclude injection subranges.
139#[derive(Clone)]
140pub struct Child {
141 /// Half-open UTF-8 byte range in the original source.
142 pub range: Range<usize>,
143 /// Whether the grammar classifies this child as named.
144 pub named: bool,
145}