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
extern crate xml;

use self::xml::reader::{EventReader, XmlEvent};
use std::io::BufReader;
use chunk::*;

pub struct Typer {
	block: FormatBlock,
}

impl Typer {

	pub fn new() -> Self {
		Self {
			block: FormatBlock::new(),
		}
	}


	pub fn parse(&mut self, xml_string: &str) -> Vec<FormatBlock> {

		let file = BufReader::new(xml_string.as_bytes());
		let parser = EventReader::new(file);
		
		let mut blocks: Vec<FormatBlock> = Vec::new();
		let mut level: usize = 0;

		fn get_chunk<'a>(chunk: &'a mut FormatChunk, level:usize) -> Option<&'a mut FormatChunk> {
			if level == 0 {
				return Some(chunk);
			}
			let elem = chunk.chunks
				.iter_mut()
				.filter(|e| if let FormatChunks::Chunk(_) = e {true} else {false})
				.last()
				.unwrap();

			if let FormatChunks::Chunk(chunk) = elem {
				return get_chunk(chunk, level-1);
			}
			None
		}

		for e in parser {
			match e {
				Ok( XmlEvent::StartElement { name, attributes, .. } ) => {
					match &name.local_name[..] {
						"block" => {
							level = 0;
							let mut block = self.block.new_empty();
							for attribute in attributes {
								block.set_attribute(&attribute.name.local_name, &attribute.value);
							}
							blocks.push(block);
						}
						"s" => {
							let block = blocks
								.last_mut()
								.expect("uou mast create <block> for <s>");
							
							let chunk = get_chunk(&mut block.chunk, level)
								.unwrap();
							let mut new_chunk = chunk.new_empty();
							for attribute in attributes {
								new_chunk.set_attribute(&attribute.name.local_name, &attribute.value);
							}
							chunk.chunks.push(FormatChunks::Chunk(new_chunk));
							level += 1;
						}
						_=>{}
					}
				}
				Ok( XmlEvent::EndElement{name, ..} ) => {
					match &name.local_name[..] {
						"block" => {
							level = 0;
						}
						"s" => {
							level -= 1;
						}
						_=>{}
					}
				}
				Ok( XmlEvent::Characters(str_chunks) ) | Ok( XmlEvent::Whitespace(str_chunks) ) => {
					if level > 0 {
						let block = blocks
							.last_mut()
							.expect("text must by in <s>");

						let chunk = get_chunk(&mut block.chunk, level).unwrap();
						chunk.chunks.push(FormatChunks::String(str_chunks));
					}
				}
				Err(e) => {
					println!("Error: {}", e);
					break;
				}
				_ => {}
			}
		}
		
		blocks
	}
}