This repository has been archived by the owner on Jul 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
functions.rs
154 lines (139 loc) · 4.3 KB
/
functions.rs
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
use quick_xml::{events::Event, name::QName, Reader};
use super::{
error::Result,
types::{ChapterMapping, GestisResponse},
};
pub fn parse_chapters(json: &GestisResponse) -> ChapterMapping {
let mut mapping = ChapterMapping {
boiling_point: None,
cas_number: None,
h_p_signal_symbols: None,
lethal_dose: None,
agw: None,
mak: None,
melting_point: None,
molecular_formula_molar_mass: None,
water_hazard_class: None,
};
// just go through the JSON once and save references to the XML strings for each required section
for chapter in json.chapters.iter() {
match chapter.number.as_str() {
"0100" => {
for subchapter in chapter.subchapters.iter() {
if subchapter.number.as_str() == "0100" {
mapping.cas_number = subchapter.text.as_deref();
}
}
}
"0400" => {
for subchapter in chapter.subchapters.iter() {
if subchapter.number.as_str() == "0400" {
mapping.molecular_formula_molar_mass = subchapter.text.as_deref();
}
}
}
"0500" => {
for subchapter in chapter.subchapters.iter() {
if subchapter.number.as_str() == "0501" {
mapping.lethal_dose = subchapter.text.as_deref();
}
}
}
"0600" => {
for subchapter in chapter.subchapters.iter() {
match subchapter.number.as_str() {
"0602" => mapping.melting_point = subchapter.text.as_deref(),
"0603" => mapping.boiling_point = subchapter.text.as_deref(),
_ => {}
}
}
}
"1100" => {
for subchapter in chapter.subchapters.iter() {
match subchapter.number.as_str() {
"1106" => mapping.water_hazard_class = subchapter.text.as_deref(),
"1201" => mapping.agw = subchapter.text.as_deref(),
"1203" => mapping.mak = subchapter.text.as_deref(),
"1303" => mapping.h_p_signal_symbols = subchapter.text.as_deref(),
_ => {}
}
}
}
_ => {}
}
}
mapping
}
// XML parsing functions
/// Private extension for `quick_xml::Parser` with convenience functions.
pub trait ReaderExt<'a> {
/// Skips the next n occurrences of the next tag.
/// Only looks at the current level, sublevels are skipped.
fn skip(&mut self, name: QName, times: u8) -> Result<()>;
/// Finds the next occurrence of tag `name`.
fn find_start(&mut self, name: QName) -> Result<Event>;
/// Finds the next `table` tag with class attribute `class`.
fn find_table(&mut self, class: &str) -> Result<Event>;
/// This function should only be use to debug code.
///
/// It is just a convenience function that prints all remaining tags and texts of the XML.
#[cfg(debug_assertions)]
fn print_to_end(&mut self) -> Result<()>;
}
impl<'a> ReaderExt<'a> for Reader<&'a [u8]> {
fn skip(&mut self, name: QName, times: u8) -> Result<()> {
for _ in 0..times {
let _ = self.read_to_end(name)?;
}
Ok(())
}
fn find_start(&mut self, name: QName) -> Result<Event> {
loop {
match self.read_event()? {
Event::Start(e) => {
if e.name() == name {
return Ok(Event::Start(e));
}
}
Event::Eof => return Ok(Event::Eof),
_ => {}
}
}
}
fn find_table(&mut self, class: &str) -> Result<Event> {
let class: &[u8] = class.as_ref();
loop {
match self.read_event()? {
Event::Start(e) => {
if e.name() == QName(b"table")
&& e.attributes().any(|a| {
if let Ok(attr) = a {
attr.key == QName(b"class") && attr.value == class
} else {
false
}
})
{
return Ok(Event::Start(e));
}
}
Event::Eof => return Ok(Event::Eof),
_ => {}
}
}
}
#[cfg(debug_assertions)]
fn print_to_end(&mut self) -> Result<()> {
let decoder = self.decoder();
loop {
match self.read_event()? {
Event::Start(e) => println!("{}", decoder.decode(e.name().0)?),
Event::Text(e) => println!(" text: '{}'", e.unescape()?),
Event::Empty(e) => println!("empty: {}", decoder.decode(e.name().0)?),
Event::Eof => break,
_ => {}
}
}
Ok(())
}
}