Add ability to specify user-defined functions for matcher

This commit is contained in:
Dima Kudosh
2016-02-28 21:35:03 +03:00
parent b2e0c729ff
commit a99af75280
5 changed files with 51 additions and 30 deletions
+24 -20
View File
@@ -44,7 +44,6 @@ impl Opcode{
pub trait Sequence: Debug {
fn len(&self) -> usize;
fn at_index(&self, index: usize) -> Option<&str>;
fn slice(&self, start: usize, end: usize) -> Option<&str>;
}
impl Sequence for str {
@@ -52,20 +51,13 @@ impl Sequence for str {
self.len()
}
fn slice(&self, start: usize, end: usize) -> Option<&str> {
if start >= end{
return None
}
if start > self.len() || end > self.len(){
return None
}
unsafe{
Some(self.slice_unchecked(start, end))
}
}
fn at_index(&self, index: usize) -> Option<&str> {
self.slice(index, index + 1)
if index > self.len(){
return None
}
unsafe{
Some(self.slice_unchecked(index, index + 1))
}
}
}
@@ -74,10 +66,6 @@ impl<'a> Sequence for Vec<&'a str> {
self.len()
}
fn slice(&self, start: usize, end: usize) -> Option<&str> {
None
}
fn at_index(&self, index: usize) -> Option<&str> {
if index < self.len() && index >= 0 {
return Some(self[index])
@@ -91,7 +79,7 @@ pub struct SequenceMatcher<'a, T: 'a + ?Sized + Sequence>{
second_sequence: &'a T,
matching_blocks: Option<Vec<Match>>,
opcodes: Option<Vec<Opcode>>,
autojunk: bool,
is_junk: Option<fn(&str) -> bool>,
second_sequence_elements: HashMap<&'a str, Vec<usize>>,
second_sequence_popular: Vec<&'a str>
}
@@ -105,7 +93,7 @@ impl<'a, T: ?Sized + Sequence> SequenceMatcher<'a, T>{
second_sequence: second_sequence,
matching_blocks: None,
opcodes: None,
autojunk: true,
is_junk: None,
second_sequence_elements: HashMap::new(),
second_sequence_popular: Vec::new()
};
@@ -113,6 +101,11 @@ impl<'a, T: ?Sized + Sequence> SequenceMatcher<'a, T>{
matcher
}
pub fn set_is_junk(&mut self, is_junk: Option<fn(&str) -> bool>) {
self.is_junk = is_junk;
self.set_second_seq(self.second_sequence);
}
pub fn set_seqs(&mut self, first_sequence: &'a T, second_sequence: &'a T) {
self.set_first_seq(first_sequence);
self.set_second_seq(second_sequence);
@@ -138,6 +131,17 @@ impl<'a, T: ?Sized + Sequence> SequenceMatcher<'a, T>{
let mut counter = second_sequence_elements.entry(second_sequence.at_index(i).unwrap()).or_insert(Vec::new());
counter.push(i);
}
if self.is_junk.is_some() {
let mut junk = Vec::new();
for element in second_sequence_elements.keys() {
if (self.is_junk.unwrap())(element) {
junk.push(element.clone());
}
}
for element in &junk {
second_sequence_elements.remove(element);
}
}
let mut popular = Vec::new();
let len = second_sequence.len();
if len >= 200 {