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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use std::io::{prelude::*, BufReader, BufWriter};
use std::marker::PhantomData;
use socarel::{Forest, NodeContent, RawNode};
use crate::stack::*;
use crate::parser::*;
use crate::error::*;
pub struct Model<T: NodeContent = RawNode>(PhantomData<T>);
impl<T: NodeContent> Model<T> {
pub fn parse(reader: BufReader<impl Read>) -> Result<Forest<T>, ParseTreeError> {
let parser = TreeParser::new();
let mut stack = NodeStack::new();
let mut prev_level = 0;
let mut current_tree_id = String::new();
let mut forest = Forest::<T>::new();
for (i, l) in reader.lines().enumerate() {
if let Ok(line) = l {
let statement = parser.parse_statement(&line);
match statement {
TreeStatement::Invalid => {
return Result::Err(ParseTreeError::new("Invalid statement", i))
},
TreeStatement::TreeID(tree_id) => {
stack.flush();
forest.new_tree(&tree_id);
current_tree_id = tree_id;
}
TreeStatement::Node(content, level) => {
if level > prev_level + 1 {
return Result::Err(ParseTreeError::new("Invalid node level", i));
}
if level == 1 {
if let Some(_) = stack.top() {
return Result::Err(ParseTreeError::new("Multiple root nodes in the same tree", i));
}
if let Some(tree) = forest.get_mut_tree(¤t_tree_id) {
if let None = tree.set_root(&content) {
return Result::Err(ParseTreeError::new("Failed parsing root node", i));
}
stack.push_new(1, 0);
}
else {
return Result::Err(ParseTreeError::new("Found root node without previous tree ID", i));
}
}
else {
if let Some(parent_node_ref) = stack.pop_parent(level) {
if let Some(tree) = forest.get_mut_tree(¤t_tree_id) {
if let Some(new_node) = tree.link_node(&content, parent_node_ref.tree_position) {
stack.push(parent_node_ref);
stack.push_new(level, new_node);
}
else {
return Result::Err(ParseTreeError::new("Failed parsing node", i));
}
}
else {
return Result::Err(ParseTreeError::new("Couldn't find tree", i));
}
}
else {
return Result::Err(ParseTreeError::new("Couldn't find a parent ref", i));
}
}
prev_level = level;
},
_ => {}
}
}
else {
return Result::Err(ParseTreeError::new("Could not read line", i));
}
}
Result::Ok(forest)
}
pub fn serialize(forest: &Forest<T>, writer: &mut BufWriter<impl Write>) -> Result<usize, SerializeTreeError> {
let parser = TreeParser::new();
let mut num_lines_writen = 0;
for (tree_id, _) in forest.iter() {
let tree_id_statement = format!("[{}]", tree_id);
if let TreeStatement::TreeID(_) = parser.parse_statement(&tree_id_statement) {
if let Err(_) = writer.write(&format!("{}\n",tree_id_statement).as_bytes()) {
return Result::Err(SerializeTreeError::new("Could not write Tree ID", num_lines_writen, Some(tree_id_statement)));
}
num_lines_writen += 1;
}
else {
return Result::Err(SerializeTreeError::new("Could not parse Tree ID", num_lines_writen, Some(tree_id_statement)));
}
if let Some(tree) = forest.get_tree(tree_id) {
for (n, _) in tree.iterators().pre_dfs() {
let mut node_statement = String::new();
for _ in 0..n.get_level() {
node_statement.push_str("+ ");
}
node_statement.push_str(&format!("{}", n.get_content_ref().gen_content()));
if let TreeStatement::Node(_,_) = parser.parse_statement(&node_statement) {
if let Err(_) = writer.write(format!("{}\n", node_statement).as_bytes()) {
return Result::Err(SerializeTreeError::new("Could nod write node", num_lines_writen, Some(node_statement)));
}
num_lines_writen += 1;
}
else {
return Result::Err(SerializeTreeError::new("Could not parse node", num_lines_writen, Some(node_statement)));
}
}
}
else {
return Result::Err(SerializeTreeError::new("Could nod get tree from forest", num_lines_writen, Some(String::from(tree_id))));
}
}
if let Err(_) = writer.flush() {
Result::Err(SerializeTreeError::new("Writer flush failed", num_lines_writen, None))
}
else {
Ok(num_lines_writen)
}
}
}