1
1
pub mod dmidecoder {
2
2
use std:: collections:: HashMap ;
3
-
3
+
4
+ /// Property represents a single item inside a section
5
+ /// it contains value and items as vector
6
+ /// you should have at least on of these fields set
4
7
#[ derive( Debug ) ]
5
8
pub struct Property {
6
9
pub value : String ,
7
10
pub items : Vec < String > ,
8
11
}
9
12
10
13
impl Property {
14
+ /// Returns empty property
15
+ /// # examples
16
+ /// ```
17
+ /// let property: Property = Property::new();
18
+ /// ```
11
19
pub fn new ( ) -> Property {
12
20
Property {
13
21
value : String :: new ( ) ,
14
22
items : Vec :: new ( ) ,
15
23
}
16
24
}
25
+ /// Check if the property is empty
26
+ /// # examples
27
+ /// ```
28
+ /// property.is_empty()
29
+ /// ```
17
30
pub fn is_empty ( & self ) -> bool {
18
31
return self . value . is_empty ( ) && self . items . is_empty ( )
19
32
}
20
33
}
21
34
35
+ /// Section represents a full section of data
22
36
#[ derive( Debug ) ]
23
37
pub struct Section {
24
38
pub handle_line : String ,
25
39
pub properties : HashMap < String , Property > ,
26
40
}
27
41
28
42
impl Section {
43
+ /// Returns empty Section
44
+ /// # examples
45
+ /// ```
46
+ /// let section: Section = Section::new();
47
+ /// ```
29
48
fn new ( ) -> Section {
30
49
Section {
31
50
handle_line : String :: new ( ) ,
32
51
properties : HashMap :: new ( ) ,
33
52
}
34
53
}
54
+ /// Check if the section is empty
55
+ /// # examples
56
+ /// ```
57
+ /// section.is_empty()
58
+ /// ```
35
59
fn is_empty ( & self ) -> bool {
36
60
return self . handle_line . is_empty ( ) && self . properties . is_empty ( )
37
61
}
38
62
}
39
63
64
+ /// State will be used in parsing
65
+ /// will indecate how to handle the current line
40
66
#[ derive( Debug ) ]
41
67
enum State {
42
68
Section ,
43
69
Kv ,
44
70
List ,
45
71
}
46
-
72
+ /// clean string by removing white spaces from the begining
47
73
fn clean_str ( line : & str ) -> String {
48
74
let mut i = 0 ;
49
75
for c in line. chars ( ) {
@@ -55,6 +81,7 @@ pub mod dmidecoder {
55
81
}
56
82
return String :: from ( line. to_string ( ) )
57
83
}
84
+ /// get the current indentation level by counting the white spaces or taps
58
85
fn get_indentation ( line : & str ) -> u8 {
59
86
let mut count = 0 ;
60
87
for c in line. chars ( ) {
@@ -66,7 +93,7 @@ pub mod dmidecoder {
66
93
}
67
94
return count;
68
95
}
69
-
96
+ /// decide the current state of the line
70
97
fn get_state ( state : State , line : & str , last_indentation : u8 ) -> State {
71
98
let mut new_state = State :: Section ;
72
99
let indentation = get_indentation ( line) ;
@@ -93,7 +120,7 @@ pub mod dmidecoder {
93
120
}
94
121
return new_state;
95
122
}
96
-
123
+ // Parse data into sections hashmap
97
124
pub fn parse ( data : & str ) -> HashMap < String , Section > {
98
125
let mut sections = HashMap :: new ( ) ;
99
126
let mut state = State :: Section ;
@@ -104,12 +131,17 @@ pub mod dmidecoder {
104
131
let mut last_indentation = 0 ;
105
132
106
133
for line in data. lines ( ) {
134
+ // decide state
107
135
let indentation = get_indentation ( line) ;
108
136
state = get_state ( state, line, last_indentation) ;
109
137
last_indentation = indentation;
138
+ // match the state to parse each line
110
139
match state {
111
140
State :: Section => {
112
141
if line. starts_with ( "Handle" ) {
142
+ // when we find handle line this means it's the begining of a new section
143
+ // so we will push the last section if it's not empty
144
+ // and create another one with the found handle line
113
145
if !current_section. is_empty ( ) && !current_section_name. is_empty ( ) {
114
146
if !current_property. is_empty ( ) && !current_property_name. is_empty ( ) {
115
147
current_section. properties . insert ( current_property_name, current_property) ;
@@ -121,11 +153,13 @@ pub mod dmidecoder {
121
153
current_section_name = String :: new ( ) ;
122
154
}
123
155
current_section. handle_line = clean_str ( line) ;
156
+ // if we have the handle line already we will read the follopwing line as the title
124
157
} else if !current_section. handle_line . is_empty ( ) && !line. is_empty ( ) {
125
158
current_section_name = clean_str ( line) ;
126
159
}
127
160
} ,
128
161
State :: Kv => {
162
+ // will check if we have current properety data to push before creating another one from the current line
129
163
if !current_property. is_empty ( ) && !current_property_name. is_empty ( ) {
130
164
current_section. properties . insert ( current_property_name, current_property) ;
131
165
current_property = Property :: new ( ) ;
@@ -141,6 +175,7 @@ pub mod dmidecoder {
141
175
}
142
176
}
143
177
}
178
+ // finalize by pushing the last property and the current section if there is data00
144
179
if !current_property. is_empty ( ) && !current_property_name. is_empty ( ) {
145
180
current_section. properties . insert ( current_property_name, current_property) ;
146
181
}
0 commit comments