Jakub Kotur | 3bceaeb | 2020-12-21 17:28:16 +0100 | [diff] [blame] | 1 | use fst::Automaton; |
| 2 | |
| 3 | use crate::{StateID, DFA}; |
| 4 | |
| 5 | macro_rules! imp { |
| 6 | ($ty:ty, $id:ty) => { |
| 7 | impl<T: AsRef<[$id]>, S: StateID> Automaton for $ty { |
| 8 | type State = S; |
| 9 | |
| 10 | #[inline] |
| 11 | fn start(&self) -> S { |
| 12 | self.start_state() |
| 13 | } |
| 14 | |
| 15 | #[inline] |
| 16 | fn is_match(&self, state: &S) -> bool { |
| 17 | self.is_match_state(*state) |
| 18 | } |
| 19 | |
| 20 | #[inline] |
| 21 | fn accept(&self, state: &S, byte: u8) -> S { |
| 22 | self.next_state(*state, byte) |
| 23 | } |
| 24 | |
| 25 | #[inline] |
| 26 | fn can_match(&self, state: &S) -> bool { |
| 27 | !self.is_dead_state(*state) |
| 28 | } |
| 29 | } |
| 30 | }; |
| 31 | } |
| 32 | |
| 33 | imp!(crate::dense::DenseDFA<T, S>, S); |
| 34 | imp!(crate::dense::Standard<T, S>, S); |
| 35 | imp!(crate::dense::ByteClass<T, S>, S); |
| 36 | imp!(crate::dense::Premultiplied<T, S>, S); |
| 37 | imp!(crate::dense::PremultipliedByteClass<T, S>, S); |
| 38 | imp!(crate::sparse::SparseDFA<T, S>, u8); |
| 39 | imp!(crate::sparse::Standard<T, S>, u8); |
| 40 | imp!(crate::sparse::ByteClass<T, S>, u8); |
| 41 | |
| 42 | #[cfg(test)] |
| 43 | mod tests { |
| 44 | use bstr::BString; |
| 45 | use fst::{Automaton, IntoStreamer, Set, Streamer}; |
| 46 | |
| 47 | use crate::dense::{self, DenseDFA}; |
| 48 | use crate::sparse::SparseDFA; |
| 49 | |
| 50 | fn search<A: Automaton, D: AsRef<[u8]>>( |
| 51 | set: &Set<D>, |
| 52 | aut: A, |
| 53 | ) -> Vec<BString> { |
| 54 | let mut stream = set.search(aut).into_stream(); |
| 55 | |
| 56 | let mut results = vec![]; |
| 57 | while let Some(key) = stream.next() { |
| 58 | results.push(BString::from(key)); |
| 59 | } |
| 60 | results |
| 61 | } |
| 62 | |
| 63 | #[test] |
| 64 | fn dense_anywhere() { |
| 65 | let set = |
| 66 | Set::from_iter(&["a", "bar", "baz", "wat", "xba", "xbax", "z"]) |
| 67 | .unwrap(); |
| 68 | let dfa = DenseDFA::new("ba.*").unwrap(); |
| 69 | let got = search(&set, &dfa); |
| 70 | assert_eq!(got, vec!["bar", "baz", "xba", "xbax"]); |
| 71 | } |
| 72 | |
| 73 | #[test] |
| 74 | fn dense_anchored() { |
| 75 | let set = |
| 76 | Set::from_iter(&["a", "bar", "baz", "wat", "xba", "xbax", "z"]) |
| 77 | .unwrap(); |
| 78 | let dfa = dense::Builder::new().anchored(true).build("ba.*").unwrap(); |
| 79 | let got = search(&set, &dfa); |
| 80 | assert_eq!(got, vec!["bar", "baz"]); |
| 81 | } |
| 82 | |
| 83 | #[test] |
| 84 | fn sparse_anywhere() { |
| 85 | let set = |
| 86 | Set::from_iter(&["a", "bar", "baz", "wat", "xba", "xbax", "z"]) |
| 87 | .unwrap(); |
| 88 | let dfa = SparseDFA::new("ba.*").unwrap(); |
| 89 | let got = search(&set, &dfa); |
| 90 | assert_eq!(got, vec!["bar", "baz", "xba", "xbax"]); |
| 91 | } |
| 92 | |
| 93 | #[test] |
| 94 | fn sparse_anchored() { |
| 95 | let set = |
| 96 | Set::from_iter(&["a", "bar", "baz", "wat", "xba", "xbax", "z"]) |
| 97 | .unwrap(); |
| 98 | let dfa = dense::Builder::new() |
| 99 | .anchored(true) |
| 100 | .build("ba.*") |
| 101 | .unwrap() |
| 102 | .to_sparse() |
| 103 | .unwrap(); |
| 104 | let got = search(&set, &dfa); |
| 105 | assert_eq!(got, vec!["bar", "baz"]); |
| 106 | } |
| 107 | } |