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
use crate::controller::*;

#[derive(Debug)]
pub enum Tree<T> {
    Leaf(T),
    Branch(Vec<Tree<T>>),
}

impl<Item> FromIterator<Tree<Item>> for Tree<Item> {
    fn from_iter<T: IntoIterator<Item = Tree<Item>>>(iter: T) -> Self {
        Tree::Branch(Vec::from_iter(iter))
    }
}

pub struct TreeAdapter<I, T, C>
where
    I: Iterator<Item = T>,
    C: Controller<T>,
{
    pub(crate) branching_controller: C,
    pub(crate) iterator: I,
}

impl<I, T, C> TreeAdapter<I, T, C>
where
    I: Iterator<Item = T>,
    C: Controller<T>,
{
    fn branch_control(&mut self, item: &T) -> BranchControl {
        self.branching_controller.control_branch(item)
    }

    fn sub_branch(&mut self, item: T) -> Tree<T> {
        let mut branches = Vec::<Tree<T>>::from([Tree::Leaf(item)]);

        loop {
            let next = match self.iterator.next() {
                Some(value) => value,
                None => break,
            };

            match self.branch_control(&next) {
                BranchControl::Start => branches.push(self.sub_branch(next)),
                BranchControl::Continue => branches.push(Tree::Leaf(next)),
                BranchControl::End => {
                    branches.push(Tree::Leaf(next));
                    break;
                }
            }
        }

        Tree::Branch(branches)
    }
}

impl<I, T, C> Iterator for TreeAdapter<I, T, C>
where
    I: Iterator<Item = T>,
    C: Controller<T>,
{
    type Item = Tree<T>;

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.iterator.next()?;

        match self.branch_control(&next) {
            BranchControl::Start => Some(self.sub_branch(next)),
            _ => Some(Tree::Leaf(next)),
        }
    }
}

pub trait Treeable<T>: Iterator<Item = T> + Sized {
    fn tree<C>(self, branching_controller: C) -> TreeAdapter<Self, T, C>
    where
        C: Controller<T>,
    {
        TreeAdapter {
            branching_controller,
            iterator: self,
        }
    }
}

impl<I, T> Treeable<T> for I where I: Iterator<Item = T> + Sized {}