1use display::*;
2use std::ops::Deref;
3
4/// Return a substring of the given ANSIStrings sequence, while keeping the formatting.
5pub fn sub_string<'a>(start: usize, len: usize, strs: &ANSIStrings<'a>) -> Vec<ANSIString<'static>> {
6 let mut vec = Vec::new();
7 let mut pos = start;
8 let mut len_rem = len;
9
10 for i in strs.0.iter() {
11 let fragment = i.deref();
12 let frag_len = fragment.len();
13 if pos >= frag_len {
14 pos -= frag_len;
15 continue;
16 }
17 if len_rem <= 0 {
18 break;
19 }
20
21 let end = pos + len_rem;
22 let pos_end = if end >= frag_len { frag_len } else { end };
23
24 vec.push(i.style_ref().paint(String::from(&fragment[pos..pos_end])));
25
26 if end <= frag_len {
27 break;
28 }
29
30 len_rem -= pos_end - pos;
31 pos = 0;
32 }
33
34 vec
35}
36
37/// Return a concatenated copy of `strs` without the formatting, as an allocated `String`.
38pub fn unstyle(strs: &ANSIStrings) -> String {
39 let mut s: String = String::new();
40
41 for i: &ANSIGenericString<'_, str> in strs.0.iter() {
42 s += &i.deref();
43 }
44
45 s
46}
47
48/// Return the unstyled length of ANSIStrings. This is equaivalent to `unstyle(strs).len()`.
49pub fn unstyled_len(strs: &ANSIStrings) -> usize {
50 let mut l: usize = 0;
51 for i: &ANSIGenericString<'_, str> in strs.0.iter() {
52 l += i.deref().len();
53 }
54 l
55}
56
57#[cfg(test)]
58mod test {
59 use Colour::*;
60 use display::*;
61 use super::*;
62
63 #[test]
64 fn test() {
65 let l = [
66 Black.paint("first"),
67 Red.paint("-second"),
68 White.paint("-third"),
69 ];
70 let a = ANSIStrings(&l);
71 assert_eq!(unstyle(&a), "first-second-third");
72 assert_eq!(unstyled_len(&a), 18);
73
74 let l2 = [
75 Black.paint("st"),
76 Red.paint("-second"),
77 White.paint("-t"),
78 ];
79 assert_eq!(sub_string(3, 11, &a).as_slice(), &l2);
80 }
81}
82