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
8 changes: 3 additions & 5 deletions harper-core/src/patterns/all.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::Pattern;
Expand All @@ -24,14 +22,14 @@ impl All {
}

impl Pattern for All {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
let mut max = 0;

for pattern in &self.children {
let len = pattern.matches(tokens, source)?;
max = max.max(len.get());
max = max.max(len);
}

NonZeroUsize::new(max)
Some(max)
}
}
6 changes: 2 additions & 4 deletions harper-core/src/patterns/any_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::Pattern;
Expand All @@ -8,7 +6,7 @@ use super::Pattern;
pub struct AnyPattern;

impl Pattern for AnyPattern {
fn matches(&self, tokens: &[Token], _source: &[char]) -> Option<NonZeroUsize> {
NonZeroUsize::new(if tokens.is_empty() { 0 } else { 1 })
fn matches(&self, tokens: &[Token], _source: &[char]) -> Option<usize> {
if tokens.is_empty() { None } else { Some(1) }
}
}
22 changes: 13 additions & 9 deletions harper-core/src/patterns/either_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::Pattern;
Expand All @@ -21,17 +19,23 @@ impl EitherPattern {
}

impl Pattern for EitherPattern {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
let mut longest = 0;
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
let mut longest = None;

for pattern in self.patterns.iter() {
let match_len = pattern.matches(tokens, source).map_or(0, NonZeroUsize::get);

if match_len > longest {
longest = match_len
let Some(match_len) = pattern.matches(tokens, source) else {
continue;
};

if let Some(longest_len) = longest {
if match_len > longest_len {
longest = Some(match_len);
}
} else {
longest = Some(match_len);
}
}

NonZeroUsize::new(longest)
longest
}
}
4 changes: 1 addition & 3 deletions harper-core/src/patterns/exact_phrase.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::{Document, Token, TokenKind};

use super::{Pattern, SequencePattern, Word};
Expand Down Expand Up @@ -46,7 +44,7 @@ impl ExactPhrase {
}

impl Pattern for ExactPhrase {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
self.inner.matches(tokens, source)
}
}
12 changes: 5 additions & 7 deletions harper-core/src/patterns/implies_quantity.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::{Token, TokenKind};

use super::Pattern;
Expand Down Expand Up @@ -38,12 +36,12 @@ impl ImpliesQuantity {
}

impl Pattern for ImpliesQuantity {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
NonZeroUsize::new(if Self::implies_plurality(tokens, source).is_some() {
1
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
if Self::implies_plurality(tokens, source).is_some() {
Some(1)
} else {
0
})
None
}
}
}

Expand Down
4 changes: 1 addition & 3 deletions harper-core/src/patterns/indefinite_article.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::{Pattern, WordSet};
Expand All @@ -17,7 +15,7 @@ impl Default for IndefiniteArticle {
}

impl Pattern for IndefiniteArticle {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
self.inner.matches(tokens, source)
}
}
4 changes: 1 addition & 3 deletions harper-core/src/patterns/inflection_of_be.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZero;

use super::Pattern;
use crate::Token;
use crate::patterns::WordSet;
Expand All @@ -26,7 +24,7 @@ impl InflectionOfBe {
}

impl Pattern for InflectionOfBe {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZero<usize>> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
self.inner.matches(tokens, source)
}
}
12 changes: 5 additions & 7 deletions harper-core/src/patterns/invert.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::Pattern;
Expand All @@ -18,11 +16,11 @@ impl Invert {
}

impl Pattern for Invert {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
NonZeroUsize::new(if self.inner.matches(tokens, source).is_some() {
0
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
if self.inner.matches(tokens, source).is_some() {
None
} else {
1
})
Some(1)
}
}
}
27 changes: 18 additions & 9 deletions harper-core/src/patterns/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
//!
//! See the page about [`SequencePattern`] for a concrete example of their use.

use std::num::NonZeroUsize;

use crate::{Document, Span, Token};

mod all;
Expand Down Expand Up @@ -57,15 +55,15 @@ pub trait Pattern {
/// Check if the pattern matches at the start of the given token slice.
///
/// Returns the length of the match if successful, or `None` if not.
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize>;
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize>;
}
#[cfg(feature = "concurrent")]
#[blanket(derive(Arc))]
pub trait Pattern: Send + Sync {
/// Check if the pattern matches at the start of the given token slice.
///
/// Returns the length of the match if successful, or `None` if not.
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize>;
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize>;
}

pub trait PatternExt {
Expand All @@ -81,6 +79,9 @@ impl<P> PatternExt for P
where
P: Pattern + ?Sized,
{
fn find_all_matches(&self, tokens: &[Token], source: &[char]) -> Vec<Span> {
self.iter_matches(tokens, source).collect()
}
fn iter_matches(&self, tokens: &[Token], source: &[char]) -> impl Iterator<Item = Span> {
MatchIter::new(self, tokens, source)
}
Expand Down Expand Up @@ -117,8 +118,8 @@ where
.pattern
.matches(&self.tokens[self.index..], self.source)
{
let span = Span::new_with_len(self.index, len.get());
self.index += len.get();
let span = Span::new_with_len(self.index, len);
self.index += len.max(1);
return Some(span);
} else {
self.index += 1;
Expand Down Expand Up @@ -148,8 +149,12 @@ where
F: Fn(&Token, &[char]) -> bool,
F: Send + Sync,
{
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
NonZeroUsize::new(if self(tokens.first()?, source) { 1 } else { 0 })
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
if self(tokens.first()?, source) {
Some(1)
} else {
None
}
}
}

Expand All @@ -159,7 +164,11 @@ where
F: Fn(&Token, &[char]) -> bool,
{
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
NonZeroUsize::new(if self(tokens.first()?, source) { 1 } else { 0 })
if self(tokens.first()?, source) {
Some(1)
} else {
None
}
}
}

Expand Down
4 changes: 1 addition & 3 deletions harper-core/src/patterns/naive_pattern_group.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use super::Pattern;
use crate::Token;

Expand All @@ -17,7 +15,7 @@ impl NaivePatternGroup {
}

impl Pattern for NaivePatternGroup {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
self.patterns
.iter()
.filter_map(|p| p.matches(tokens, source))
Expand Down
6 changes: 2 additions & 4 deletions harper-core/src/patterns/nominal_phrase.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::Token;

use super::Pattern;
Expand All @@ -8,7 +6,7 @@ use super::Pattern;
pub struct NominalPhrase;

impl Pattern for NominalPhrase {
fn matches(&self, tokens: &[Token], _source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], _source: &[char]) -> Option<usize> {
let mut cursor = 0;

loop {
Expand All @@ -26,7 +24,7 @@ impl Pattern for NominalPhrase {
}

if tok.kind.is_nominal() {
return NonZeroUsize::new(cursor + 1);
return Some(cursor + 1);
}

return None;
Expand Down
4 changes: 1 addition & 3 deletions harper-core/src/patterns/pattern_map.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use crate::LSend;
use crate::Token;

Expand Down Expand Up @@ -69,7 +67,7 @@ impl<T> Pattern for PatternMap<T>
where
T: LSend,
{
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
self.rows
.iter()
.filter_map(|row| row.key.matches(tokens, source))
Expand Down
18 changes: 11 additions & 7 deletions harper-core/src/patterns/repeating_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::num::NonZeroUsize;

use super::Pattern;
use crate::Token;

Expand All @@ -21,18 +19,25 @@ impl RepeatingPattern {
}

impl Pattern for RepeatingPattern {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<NonZeroUsize> {
fn matches(&self, tokens: &[Token], source: &[char]) -> Option<usize> {
let mut tok_cursor = 0;
let mut repetition = 0;

loop {
let match_len = self.inner.matches(&tokens[tok_cursor..], source);

if let Some(match_len) = match_len {
tok_cursor += match_len.get();
if match_len == 0 {
// If match_len == 0, we won't move forward ever again.
// This means that we can get infinitely many repetitions,
// so repetition >= self.required_repetitions is guaranteed.
return Some(tok_cursor);
}

tok_cursor += match_len;
repetition += 1;
} else if repetition >= self.required_repetitions {
return NonZeroUsize::new(tok_cursor);
return Some(tok_cursor);
} else {
return None;
}
Expand All @@ -42,7 +47,6 @@ impl Pattern for RepeatingPattern {

#[cfg(test)]
mod tests {
use std::num::NonZeroUsize;

use super::RepeatingPattern;
use crate::Document;
Expand All @@ -57,7 +61,7 @@ mod tests {

assert_eq!(
pat.matches(doc.get_tokens(), doc.get_source()),
NonZeroUsize::new(doc.get_tokens().len())
Some(doc.get_tokens().len())
)
}

Expand Down
Loading