logix_type/token/string/
txt.rs

1use bstr::ByteSlice;
2
3/// Decode a string in the txt format, see StrTag::Txt
4pub fn decode_str(s: &str) -> String {
5    let mut lines = Vec::new();
6    let mut pos = 0;
7    let mut prefix_len = usize::MAX;
8
9    for l in s.as_bytes().lines_with_terminator() {
10        let raw_end = pos + l.len();
11        let end = pos + l.trim_end().len();
12
13        // Enter the if only if not the first line, or it is not a newline
14        if pos != 0 || pos != end {
15            if pos != end {
16                prefix_len = prefix_len.min(l.len() - l.trim_start().len());
17            }
18            lines.push(pos..end);
19        }
20        pos = raw_end;
21    }
22
23    // Remove the last newline
24    if let Some(true) = lines.last().map(|r| r.is_empty()) {
25        lines.pop();
26    }
27
28    let mut ret = String::with_capacity(lines.iter().map(|r| r.len().max(1)).sum());
29
30    for range in lines {
31        debug_assert!(ret.capacity() >= range.len(), "{range:?}");
32        let cur = &s[range];
33        if cur.is_empty() {
34            ret.push('\n');
35        } else {
36            ret.push_str(&cur[prefix_len..]);
37        }
38    }
39
40    ret
41}