Skip to main content

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}