Add matching mechanism
This commit is contained in:
parent
0c860c0b5f
commit
191d350650
|
@ -12,7 +12,7 @@ impl <'a> Engine<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> MatchReceiver for Engine<'a>{
|
impl <'a> MatchReceiver for Engine<'a>{
|
||||||
fn on_match(&self, m: Match) {
|
fn on_match(&self, m: &Match) {
|
||||||
self.sender.delete_string(m.trigger.len() as i32);
|
self.sender.delete_string(m.trigger.len() as i32);
|
||||||
self.sender.send_string(m.result.as_str());
|
self.sender.send_string(m.result.as_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use crate::keyboard::KeyboardInterceptor;
|
use crate::keyboard::KeyboardInterceptor;
|
||||||
use crate::matcher::Matcher;
|
use crate::matcher::Matcher;
|
||||||
|
use crate::matcher::Match;
|
||||||
use crate::matcher::scrolling::ScrollingMatcher;
|
use crate::matcher::scrolling::ScrollingMatcher;
|
||||||
use crate::engine::Engine;
|
use crate::engine::Engine;
|
||||||
|
|
||||||
|
@ -21,6 +22,8 @@ fn main() {
|
||||||
|
|
||||||
let engine = Engine::new(&sender);
|
let engine = Engine::new(&sender);
|
||||||
|
|
||||||
let matcher = ScrollingMatcher::new(&engine);
|
let matches = vec![Match{trigger:"e'".to_owned(), result: "è".to_owned()}, Match{trigger:":lol".to_owned(), result: "😂".to_owned()}];
|
||||||
|
|
||||||
|
let mut matcher = ScrollingMatcher::new(&matches, &engine);
|
||||||
matcher.watch(&rxc);
|
matcher.watch(&rxc);
|
||||||
}
|
}
|
|
@ -8,12 +8,12 @@ pub struct Match {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait MatchReceiver {
|
pub trait MatchReceiver {
|
||||||
fn on_match(&self, m: Match);
|
fn on_match(&self, m: &Match);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Matcher {
|
pub trait Matcher {
|
||||||
fn handle_char(&self, c: char);
|
fn handle_char(&mut self, c: char);
|
||||||
fn watch(&self, receiver: &Receiver<char>) {
|
fn watch(&mut self, receiver: &Receiver<char>) {
|
||||||
loop {
|
loop {
|
||||||
match receiver.recv() {
|
match receiver.recv() {
|
||||||
Ok(c) => {
|
Ok(c) => {
|
||||||
|
|
|
@ -1,21 +1,52 @@
|
||||||
use crate::matcher::{Match, MatchReceiver};
|
use crate::matcher::{Match, MatchReceiver};
|
||||||
|
|
||||||
pub struct ScrollingMatcher<'a>{
|
pub struct ScrollingMatcher<'a>{
|
||||||
receiver: &'a MatchReceiver
|
matches: &'a Vec<Match>,
|
||||||
|
receiver: &'a MatchReceiver,
|
||||||
|
current_set: Vec<MatchEntry<'a>>
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MatchEntry<'a> {
|
||||||
|
remaining: &'a str,
|
||||||
|
_match: &'a Match
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> super::Matcher for ScrollingMatcher<'a> {
|
impl <'a> super::Matcher for ScrollingMatcher<'a> {
|
||||||
fn handle_char(&self, c: char) {
|
fn handle_char(&mut self, c: char) {
|
||||||
println!("Scroll {}",c);
|
let mut new_matches: Vec<MatchEntry> = self.matches.iter()
|
||||||
|
.filter(|&x| x.trigger.chars().nth(0).unwrap() == c)
|
||||||
|
.map(|x | MatchEntry{remaining: &x.trigger[1..], _match: &x})
|
||||||
|
.collect();
|
||||||
|
// TODO: use an associative structure to improve the efficiency of this first "new_matches" lookup.
|
||||||
|
|
||||||
if c == 'a' {
|
let old_matches = self.current_set.iter()
|
||||||
self.receiver.on_match(Match{trigger: "a".to_owned(), result: "ciao".to_owned()});
|
.filter(|&x| x.remaining.chars().nth(0).unwrap() == c)
|
||||||
|
.map(|x | MatchEntry{remaining: &x.remaining[1..], _match: &x._match})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.current_set = old_matches;
|
||||||
|
self.current_set.append(&mut new_matches);
|
||||||
|
|
||||||
|
let mut found = false;
|
||||||
|
let mut foundMatch = None;
|
||||||
|
|
||||||
|
for entry in self.current_set.iter_mut() {
|
||||||
|
if entry.remaining.len() == 0 {
|
||||||
|
foundMatch = Some(entry._match);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(_match) = foundMatch {
|
||||||
|
self.current_set.clear();
|
||||||
|
self.receiver.on_match(_match);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <'a> ScrollingMatcher<'a> {
|
impl <'a> ScrollingMatcher<'a> {
|
||||||
pub fn new(receiver: &'a MatchReceiver) -> ScrollingMatcher<'a> {
|
pub fn new(matches:&'a Vec<Match>, receiver: &'a MatchReceiver) -> ScrollingMatcher<'a> {
|
||||||
ScrollingMatcher{ receiver }
|
let current_set = Vec::new();
|
||||||
|
ScrollingMatcher{ matches, receiver, current_set }
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user