1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
| | From e3576b180488b8231e1fc0ca130748577579d129 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tu=E1=BA=A5n-Anh=20Nguy=E1=BB=85n?= <ubolonton@gmail.com>
Date: Sun, 25 Jul 2021 13:11:52 +0700
Subject: [PATCH] Allow TextProvider's iterators to generate owned text
---
binding_rust/lib.rs | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs
index e88a411c..cf214d92 100644
--- a/binding_rust/lib.rs
+++ b/binding_rust/lib.rs
@@ -5,6 +5,7 @@ mod util;
use std::os::unix::io::AsRawFd;
use std::{
+ borrow::Cow,
char, error,
ffi::CStr,
fmt, hash, iter,
@@ -183,7 +184,8 @@ pub struct QueryCaptures<'a, 'tree: 'a, T: TextProvider<'a>> {
}
pub trait TextProvider<'a> {
- type I: Iterator<Item = &'a [u8]> + 'a;
+ type I: Iterator<Item = Cow<'a, [u8]>>;
+
fn text(&mut self, node: Node) -> Self::I;
}
@@ -1840,19 +1842,19 @@ impl<'a, 'tree> QueryMatch<'a, 'tree> {
buffer2: &mut Vec<u8>,
text_provider: &mut impl TextProvider<'a>,
) -> bool {
- fn get_text<'a, 'b: 'a, I: Iterator<Item = &'b [u8]>>(
+ fn get_text<'a, 'b: 'a, I: Iterator<Item = Cow<'b, [u8]>>>(
buffer: &'a mut Vec<u8>,
mut chunks: I,
- ) -> &'a [u8] {
- let first_chunk = chunks.next().unwrap_or(&[]);
+ ) -> Cow<'a, [u8]> {
+ let first_chunk = chunks.next().unwrap_or(Cow::Owned(vec![0u8; 0]));
if let Some(next_chunk) = chunks.next() {
buffer.clear();
- buffer.extend_from_slice(first_chunk);
- buffer.extend_from_slice(next_chunk);
+ buffer.extend_from_slice(&first_chunk);
+ buffer.extend_from_slice(&next_chunk);
for chunk in chunks {
- buffer.extend_from_slice(chunk);
+ buffer.extend_from_slice(&chunk);
}
- buffer.as_slice()
+ Cow::Borrowed(buffer.as_slice())
} else {
first_chunk
}
@@ -1888,7 +1890,7 @@ impl<'a, 'tree> QueryMatch<'a, 'tree> {
match node {
Some(node) => {
let text = get_text(buffer1, text_provider.text(node));
- r.is_match(text) == *is_positive
+ r.is_match(&text) == *is_positive
}
None => true,
}
@@ -2002,23 +2004,24 @@ impl<'cursor, 'tree> fmt::Debug for QueryMatch<'cursor, 'tree> {
}
}
-impl<'a, F, I> TextProvider<'a> for F
+impl<'a, F, I, T> TextProvider<'a> for F
where
F: FnMut(Node) -> I,
- I: Iterator<Item = &'a [u8]> + 'a,
+ T: Into<Cow<'a, [u8]>>,
+ I: Iterator<Item = T>,
{
- type I = I;
+ type I = iter::Map<I, fn(T) -> Cow<'a, [u8]>>;
fn text(&mut self, node: Node) -> Self::I {
- (self)(node)
+ (self)(node).map(T::into)
}
}
impl<'a> TextProvider<'a> for &'a [u8] {
- type I = iter::Once<&'a [u8]>;
+ type I = iter::Once<Cow<'a, [u8]>>;
fn text(&mut self, node: Node) -> Self::I {
- iter::once(&self[node.byte_range()])
+ iter::once(Cow::Borrowed(&self[node.byte_range()]))
}
}
|