From e3576b180488b8231e1fc0ca130748577579d129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tu=E1=BA=A5n-Anh=20Nguy=E1=BB=85n?= 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 + 'a; + type I: Iterator>; + fn text(&mut self, node: Node) -> Self::I; } @@ -1840,19 +1842,19 @@ impl<'a, 'tree> QueryMatch<'a, 'tree> { buffer2: &mut Vec, text_provider: &mut impl TextProvider<'a>, ) -> bool { - fn get_text<'a, 'b: 'a, I: Iterator>( + fn get_text<'a, 'b: 'a, I: Iterator>>( buffer: &'a mut Vec, 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 + 'a, + T: Into>, + I: Iterator, { - type I = I; + type I = iter::Map 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>; fn text(&mut self, node: Node) -> Self::I { - iter::once(&self[node.byte_range()]) + iter::once(Cow::Borrowed(&self[node.byte_range()])) } }