ansi_term/
util.rs

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::new();
40
41    for i 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 = 0;
51    for i 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}