1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
pub use crate::*;
pub use std::fmt::Write;
pub use std::ops::Range;

#[derive(Debug)]
pub struct Token<'a, T> {
    pub root: &'a str,
    pub t_type: TokenType<'a, T>,
    pub data: T,
}

#[derive(Debug)]
pub enum TokenType<'a, T> {
    Leaf(Range<usize>),
    Branch(Vec<Token<'a, T>>),
}

impl<'a, T> Token<'a, T> {
    pub fn token_vec_from_str(
        from: &'a str,
        data: impl Fn(&'a str, usize) -> T,
    ) -> Vec<Token<'a, T>> {
        (0..from.len())
            .map(|i| Token {
                t_type: TokenType::Leaf(i..i + 1),
                root: from,
                data: data(from, i),
            })
            .collect::<Vec<Token<T>>>()
    }

    pub fn content_range(&self) -> Range<usize> {
        match &self.t_type {
            TokenType::Leaf(r) => r.clone(),
            TokenType::Branch(children) => {
                children[0].content_range().start
                    ..children
                        .last()
                        .expect("Branch tokens should have children!")
                        .content_range()
                        .end
            }
        }
    }

    pub fn content(&self) -> &str {
        &self.root[self.content_range()]
    }

    pub fn graph(&self) -> String {
        let mut to_ret = String::new();
        self.graph_depth(0, &mut to_ret)
            .expect("Couldn't graph the token");
        to_ret
    }

    pub fn graph_vec(tox: &Vec<Token<T>>) -> String {
        tox.iter()
            .map(|i| i.graph())
            .fold(String::new(), |l, r| format!("{l}\n{r}"))
    }

    pub fn vec_content(tox: &Vec<Token<T>>) -> String {
        tox.iter()
            .map(|i| i.content())
            .fold(String::new(), |l, r| format!("{l}{r}"))
    }

    pub fn graph_depth(&self, depth: usize, buf: &mut String) -> Result<(), std::fmt::Error> {
        for _ in 0..depth {
            write!(buf, "\t")?;
        }
        match &self.t_type {
            TokenType::Branch(children) => {
                writeln!(buf, "{{")?;
                for child in children {
                    child.graph_depth(depth + 1, buf)?;
                }
                for _ in 0..depth {
                    write!(buf, "\t")?;
                }
                writeln!(buf, "}}")?;
            }
            TokenType::Leaf(_) => {
                writeln!(buf, "{}", self.content())?;
            }
        }

        Ok(())
    }
}