1use std::cmp;
2use crate::{Utf16Char, Utf16String};
3
4
5pub fn shrink(tail: Utf16String, mut begs: Vec<i32>, mut lens: Vec<Utf16Char>)
11 -> (Utf16String, Vec<i32>, Vec<Utf16Char>) {
12 let mut new_tail: Utf16String;
13 {
14 let sorted: Vec<TailString> = {
16 let mut list = Vec::with_capacity(begs.len());
17 for i in 0..begs.len() {
18 list.push(TailString {
19 id: i,
20 s: &tail[(begs[i] as usize)..(begs[i] as usize + lens[i] as usize)]
21 });
22 }
23 list.sort();
24 list
25 };
26
27 new_tail = Vec::new();
30 for i in 0..sorted.len() {
31 let ts = &sorted[i];
32
33 let mut beg_index = new_tail.len();
34 if i > 0 && sorted[i - 1].s.ends_with(ts.s) {
35 beg_index -= ts.s.len(); } else {
37 new_tail.extend_from_slice(ts.s); }
39
40 begs[ts.id] = beg_index as i32;
42 lens[ts.id] = ts.s.len() as Utf16Char;
43 }
44 }
45
46 (new_tail, begs, lens)
47}
48
49struct TailString<'a> {
50 id: usize,
51 s: &'a [Utf16Char]
52}
53
54impl<'a> cmp::Ord for TailString<'a> {
55 fn cmp(&self, ts: &Self) -> cmp::Ordering {
57 let mut i = self.s.len() as isize - 1;
58 let mut j = ts.s.len() as isize - 1;
59 loop {
60 if i < 0 {
61 if j < 0 {
62 return cmp::Ordering::Equal;
63 } else {
64 return cmp::Ordering::Greater;
65 }
66 } else if j < 0 || self.s[i as usize] > ts.s[j as usize] {
67 return cmp::Ordering::Less;
68 } else if self.s[i as usize] < ts.s[j as usize] {
69 return cmp::Ordering::Greater;
70 }
71
72 i -= 1;
73 j -= 1;
74 }
75 }
76}
77
78impl<'a> cmp::PartialOrd for TailString<'a> {
79 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
80 Some(self.cmp(other))
81 }
82}
83
84impl<'a> cmp::PartialEq for TailString<'a> {
85 fn eq(&self, other: &Self) -> bool {
86 self.s.eq(other.s)
87 }
88}
89
90impl<'a> cmp::Eq for TailString<'a> {}