use super::traits::*;
use crate::search_by;
type SuffixTerm<T, XFix = Suffix> = (T, XFix);
#[derive(Debug, Clone)]
pub struct SuffixMatchDictPair<T> {
pub(super) suffixes: Vec<SuffixTerm<T>>,
}
impl<T> Default for SuffixMatchDictPair<T> {
fn default() -> Self {
Self {
suffixes: Vec::new(),
}
}
}
#[macro_export]
macro_rules! suffix_match_dict_pair {
(@value $v:literal) => {
$v.into()
};
(@value $v:expr) => {
$v
};
[$($suffix:expr => $item:expr $(,)?)*] => {{
let mut d = $crate::SuffixMatchDictPair::default();
$(
d.insert((
suffix_match_dict_pair!(@value $suffix),
suffix_match_dict_pair!(@value $item),
));
)*
d
}};
}
impl<T> SuffixMatchDictPair<T> {
pub fn new(suffixes: impl IntoIterator<Item = SuffixTerm<T, impl Into<Suffix>>>) -> Self {
let mut dict = Self::default();
for term_to_into in suffixes.into_iter() {
dict.insert(Self::new_suffix_term(term_to_into.1.into(), term_to_into.0));
}
dict
}
#[inline(always)]
pub fn suffix_ref_of(term: &SuffixTerm<T>) -> &Suffix {
&term.1
}
#[inline(always)]
pub fn get_associated_from_term(term: &SuffixTerm<T>) -> &T {
&term.0
}
#[inline(always)]
pub fn new_suffix_term(suffix: Suffix, associated: T) -> SuffixTerm<T> {
(associated, suffix)
}
#[inline(always)]
pub fn has(&self, suffix: &Suffix) -> bool {
self.search(suffix).is_ok()
}
pub fn insert(&mut self, term: SuffixTerm<T>) -> Option<usize> {
if let Err(index) = self.search(Self::get_suffix_from_term(&term)) {
self.suffixes.insert(index, term);
return Some(index);
}
None
}
#[inline(always)]
pub fn iter_terms<'a>(&'a self) -> impl Iterator<Item = &SuffixTerm<T>> + 'a
where
String: 'a,
{
self.suffixes.iter()
}
#[inline(always)]
pub fn search(&self, suffix: &SuffixStr) -> Result<usize, usize> {
search_by(&self.suffixes, &suffix, |suffix, existed| {
Self::cmp_suffix(existed, suffix) })
}
}
impl<T> SuffixMatch<SuffixTerm<T>> for SuffixMatchDictPair<T> {
fn get_suffix_from_term(term: &SuffixTerm<T>) -> &SuffixStr {
Self::suffix_ref_of(term)
}
fn suffix_terms<'a>(&'a self) -> impl Iterator<Item = &'a SuffixTerm<T>> + 'a
where
SuffixTerm<T>: 'a,
{
self.iter_terms()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{show, test_match_suffix};
#[test]
fn test_edge() {
let d: SuffixMatchDictPair<String> = suffix_match_dict_pair!(
"0" => "" "1" => "a"
"2" => "aa"
"3" => "aaa"
);
show!(&d);
test_match_suffix! {
d;
"a" => Some("1")
"aa" => Some("2")
"aaa" => Some("3")
"_a" => Some("1")
"_aa" => Some("2")
"_aaa" => Some("3")
"" => Some("0")
"b" => Some("0")
}
}
#[test]
fn test_suffix_match_pairs() {
let d: SuffixMatchDictPair<String> = suffix_match_dict_pair!(
"(" => ")"
"[" => "]"
"{" => "}"
"<" => ">"
);
show!(&d);
test_match_suffix! {
d;
r"(A, B, C)" => Some("(")
r"[A, B, C]" => Some("[")
r"{A, B, C}" => Some("{")
r"<A, B, C>" => Some("<")
"word" => None
}
let d: SuffixMatchDictPair<String> = suffix_match_dict_pair!(
"%" => "%"
r"\langle{}" => r"\rangle{}"
"真" => "值"
"" => r":\:" "" => r":|:" "" => r":/:" ":!" => r":" "" => r"\backslash\!\!\!\Rightarrow{}" "" => r"|\!\!\!\Rightarrow{}" "" => r"/\!\!\!\Rightarrow{}" "t=" => "", "" => "过去" "" => "现在" "" => "将来" );
show!(&d);
test_match_suffix! {
d;
r"<A --> B>. :\:" => Some("") r"<A --> B>. :|:" => Some("") r"<A --> B>. :/:" => Some("") r"<A --> B>. :!-137:" => Some(r":!")
r"\left<A \rightarrow{} B\right>. \backslash\!\!\!\Rightarrow{}" => Some("")
r"\left<A \rightarrow{} B\right>. |\!\!\!\Rightarrow{}" => Some("")
r"\left<A \rightarrow{} B\right>. /\!\!\!\Rightarrow{}" => Some("")
r"\left<A \rightarrow{} B\right>." => Some("t=") "「A是B」。过去" => Some("")
"「A是B」。现在" => Some("")
"「A是B」。将来" => Some("")
}
}
}