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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use crate::Node;
use crate::Reader;
use crate::ReadItemKind;
pub fn read_into_tree<R: Reader>(reader: &mut R) -> Result<Node, R::Error> {
struct StackItem {
list_items: Vec<Node>,
}
enum State {
Beginning,
Reading {
stack: Vec<StackItem>,
current: StackItem,
},
Finished(Node),
}
let mut state = State::Beginning;
loop {
match state {
State::Beginning => {
let item = reader.read()?;
match item.kind {
ReadItemKind::Atom(atom) => {
let root_node = Node::Atom(atom.into());
state = State::Finished(root_node);
}
ReadItemKind::ListBeginning => {
state = State::Reading {
stack: Vec::new(),
current: StackItem {
list_items: Vec::new(),
},
};
}
ReadItemKind::ListEnding => panic!("unexpected list ending"),
}
}
State::Reading { ref mut stack, ref mut current } => {
let item = reader.read()?;
match item.kind {
ReadItemKind::Atom(atom) => {
current.list_items.push(Node::Atom(atom.into()));
}
ReadItemKind::ListBeginning => {
let new_current = StackItem {
list_items: Vec::new(),
};
stack.push(std::mem::replace(current, new_current));
}
ReadItemKind::ListEnding => {
if let Some(previous) = stack.pop() {
let old_current = std::mem::replace(current, previous);
current.list_items.push(Node::List(old_current.list_items));
} else {
let root_node = Node::List(std::mem::replace(&mut current.list_items, Vec::new()));
state = State::Finished(root_node);
}
}
}
}
State::Finished(root_node) => return Ok(root_node),
}
}
}