Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "noa-parser"
version = "0.6.0"
version = "0.7.0"
edition = "2024"
homepage = "https://github.com/Akanoa/noa-parser"
repository = "https://github.com/Akanoa/noa-parser"
Expand Down
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

**0.7.0**

- Allow to peek until a specific element

**0.6.0**

- Add Recognizer
Expand Down
51 changes: 44 additions & 7 deletions src/peek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::errors::ParseResult;
use crate::matcher::MatchSize;
use crate::recognizer::{Recognizable, recognize};
use crate::recognizer::RecognizeSelf;
use crate::scanner::Scanner;
use std::marker::PhantomData;

Expand All @@ -32,7 +32,14 @@ where
{
/// Get a slice of the data that was peeked.
pub fn peeked_slice(&self) -> &'a [T] {
&self.data[0 + self.start.size()..self.end_slice - self.end.size()]
&self.data[self.start.size()..self.end_slice - self.end.size()]
}

/// Get the data that was peeked.
///
/// Returns a reference to the underlying data that was peeked.
pub fn data(&self) -> &'a [T] {
self.data
}
}

Expand Down Expand Up @@ -142,9 +149,18 @@ pub struct Until<'a, T, V> {
_marker: PhantomData<&'a T>,
}

impl<'a, T, V> Until<'a, T, V> {
pub fn new(element: V) -> Until<'a, T, V> {
Until {
element,
_marker: PhantomData,
}
}
}

impl<'a, T, V> Peekable<'a, T, V, V> for Until<'a, T, V>
where
V: Recognizable<'a, T, V> + Clone,
V: RecognizeSelf<'a, T, V> + Clone,
{
/// Peek until the given `element` is found in the `Scanner`.
///
Expand All @@ -166,14 +182,18 @@ where
// create a temporary scanner to peek data
let mut scanner = Scanner::new(data.data());
while !scanner.is_empty() {
match recognize(self.element.clone(), &mut scanner) {
Ok(_element) => {
match self.element.clone().recognize_self(&mut scanner) {
Ok(Some(element)) => {
return Ok(PeekResult::Found {
end_slice: scanner.current_position() - self.element.size(),
start: self.element.clone(),
end: self.element.clone(),
start: element.clone(),
end: element.clone(),
});
}
Ok(None) => {
scanner.bump_by(1);
continue;
}
Err(_err) => {
scanner.bump_by(1);
continue;
Expand Down Expand Up @@ -213,3 +233,20 @@ impl<'a> Peekable<'a, u8, (), ()> for UntilEnd<u8> {
})
}
}

#[cfg(test)]
mod tests {
use crate::bytes::token::Token;
use crate::peek::{peek, Until};

#[test]
fn test_until() {
let data = b"abc|fdgf";
let mut scanner = crate::scanner::Scanner::new(data);
let token = Until::new(Token::Pipe);
let peeked = peek(token, &mut scanner)
.expect("failed to parse")
.expect("failed to peek");
assert_eq!(peeked.data(), "abc".as_bytes());
}
}