1use std::fs::File;
2use std::io::prelude::*;
3use std::str::FromStr;
4
5use crate::st_bridge::stb_common::StbCommon;
6use crate::st_bridge::stb_extensions::StbExtension;
7use crate::st_bridge::stb_extensions::StbExtensions;
8use crate::st_bridge::stb_model::stb_axes_and_stories::StbAxes;
9use crate::st_bridge::stb_model::stb_axes_and_stories::StbNodeId;
10use crate::st_bridge::stb_model::stb_axes_and_stories::StbNodeIdList;
11use crate::st_bridge::stb_model::stb_axes_and_stories::StbStories;
12use crate::st_bridge::stb_model::stb_axes_and_stories::StbStory;
13use crate::st_bridge::stb_model::stb_axes_and_stories::StbStoryKind;
14use crate::st_bridge::stb_model::stb_axes_and_stories::StbXAxis;
15use crate::st_bridge::stb_model::stb_axes_and_stories::StbYAxis;
16use crate::st_bridge::stb_model::stb_members::HaunchType;
17use crate::st_bridge::stb_model::stb_members::StbBeam;
18use crate::st_bridge::stb_model::stb_members::StbBeams;
19use crate::st_bridge::stb_model::stb_members::StbBrace;
20use crate::st_bridge::stb_model::stb_members::StbBraces;
21use crate::st_bridge::stb_model::stb_members::StbColumn;
22use crate::st_bridge::stb_model::stb_members::StbColumns;
23use crate::st_bridge::stb_model::stb_members::StbGirder;
24use crate::st_bridge::stb_model::stb_members::StbGirders;
25use crate::st_bridge::stb_model::stb_members::StbMembers;
26use crate::st_bridge::stb_model::stb_members::StbPost;
27use crate::st_bridge::stb_model::stb_members::StbPosts;
28use crate::st_bridge::stb_model::stb_members::StbSlab;
29use crate::st_bridge::stb_model::stb_members::StbSlabs;
30use crate::st_bridge::stb_model::stb_nodes::StbNode;
31use crate::st_bridge::stb_model::stb_nodes::StbNodes;
32use crate::st_bridge::stb_model::stb_sections::StbSec1WaySlab1;
33use crate::st_bridge::stb_model::stb_sections::StbSecBarArrangementBeam;
34use crate::st_bridge::stb_model::stb_sections::StbSecBarArrangementSlab;
35use crate::st_bridge::stb_model::stb_sections::StbSecBeamRC;
36use crate::st_bridge::stb_model::stb_sections::StbSecBeamS;
37use crate::st_bridge::stb_model::stb_sections::StbSecBeamSameSection;
38use crate::st_bridge::stb_model::stb_sections::StbSecBeamStartCenterEndSection;
39use crate::st_bridge::stb_model::stb_sections::StbSecBraceS;
40use crate::st_bridge::stb_model::stb_sections::StbSecBuildBox;
41use crate::st_bridge::stb_model::stb_sections::StbSecBuildH;
42use crate::st_bridge::stb_model::stb_sections::StbSecColumnS;
43use crate::st_bridge::stb_model::stb_sections::StbSecFigureBeam;
44use crate::st_bridge::stb_model::stb_sections::StbSecFigureSlab;
45use crate::st_bridge::stb_model::stb_sections::StbSecHaunch;
46use crate::st_bridge::stb_model::stb_sections::StbSecPipe;
47use crate::st_bridge::stb_model::stb_sections::StbSecRollBox;
48use crate::st_bridge::stb_model::stb_sections::StbSecRollH;
49use crate::st_bridge::stb_model::stb_sections::StbSecRollL;
50use crate::st_bridge::stb_model::stb_sections::StbSecSlabRC;
51use crate::st_bridge::stb_model::stb_sections::StbSecSteel;
52use crate::st_bridge::stb_model::stb_sections::StbSecSteelBeam;
53use crate::st_bridge::stb_model::stb_sections::StbSecSteelBrace;
54use crate::st_bridge::stb_model::stb_sections::StbSecSteelColumn;
55use crate::st_bridge::stb_model::stb_sections::StbSecStraightBeam;
56use crate::st_bridge::stb_model::stb_sections::StbSecStraightSlab;
57use crate::st_bridge::stb_model::stb_sections::StbSections;
58use crate::st_bridge::stb_model::StbModel;
59use crate::st_bridge::StBridge;
60
61pub mod st_bridge;
62
63pub fn read_st_bridge(file_name: &str) -> StBridge {
64 let contents = get_contents(file_name);
65
66 let document = roxmltree::Document::parse(&contents).unwrap();
67
68 let root_node = document.root_element();
69
70 let version = root_node.attribute("version").unwrap().to_string();
71
72 let stb_common = extract_stb_common(root_node);
73
74 let stb_model = extract_stb_model(root_node);
75
76 let stb_extensions = extract_stb_extensions(root_node);
77
78 StBridge {
79 version,
80 stb_common,
81 stb_model,
82 stb_extensions,
83 }
84}
85
86pub fn get_contents(filename: &str) -> String {
87 let mut f = File::open(filename).expect("File not found.");
88
89 let mut contents = String::new();
90
91 f.read_to_string(&mut contents)
92 .expect("something went wrong reading the file");
93
94 return contents;
95}
96
97pub fn extract_node<'a>(
98 name: &str,
99 parent: roxmltree::Node<'a, '_>,
100) -> Option<roxmltree::Node<'a, 'a>> {
101 let child_elements = parent.children().filter(|n| n.is_element());
102
103 for node in child_elements {
104 let tag_name = node.tag_name().name();
105
106 if tag_name == name {
107 return Some(node);
108 }
109 }
110
111 None
112}
113
114pub fn extract_stb_common<'a>(root_node: roxmltree::Node<'a, 'a>) -> StbCommon {
115 let stb_common_node = extract_node("StbCommon", root_node).unwrap();
116 let stb_reinforcement_strength_list =
117 extract_node("StbReinforcement_Strength_List", stb_common_node).unwrap();
118 let mut stb_common = StbCommon::new();
119
120 for node in stb_reinforcement_strength_list
121 .children()
122 .filter(|n| n.is_element())
123 {
124 let d = node.attribute("D").unwrap().to_string();
125 let sd = node.attribute("SD").unwrap().to_string();
126 stb_common.stb_reinforcement_strength_list.insert(d, sd);
127 }
128
129 return stb_common;
130}
131
132pub fn extract_stb_model(root_node: roxmltree::Node) -> StbModel {
133 let stb_model_node = extract_node("StbModel", root_node).unwrap();
134
135 let stb_nodes = extract_stb_nodes(stb_model_node);
136
137 let stb_axes = extract_stb_axes(stb_model_node);
138
139 let stb_stories = extract_stb_stories(stb_model_node);
140
141 let stb_members = extract_stb_members(stb_model_node);
142
143 let stb_sections = extract_stb_sections(stb_model_node);
144
145 StbModel {
146 stb_nodes,
147 stb_axes,
148 stb_stories,
149 stb_members,
150 stb_sections,
151 }
152}
153
154fn extract_stb_nodes(stb_model_node: roxmltree::Node) -> StbNodes {
155 let stb_nodes_node = extract_node("StbNodes", stb_model_node).unwrap();
156
157 let mut stb_nodes = StbNodes::new();
158
159 for node in stb_nodes_node.children().filter(|n| n.is_element()) {
160 let id_member = match node.attribute("id_member") {
161 Some(s) => Some(s.parse::<i32>().unwrap()),
162 None => None,
163 };
164
165 stb_nodes.insert(
166 parse_attribute("id", node).unwrap(),
167 StbNode {
168 x: parse_attribute("x", node).unwrap(),
169 y: parse_attribute("y", node).unwrap(),
170 z: parse_attribute("z", node).unwrap(),
171 kind: parse_enum_attribute("kind", node).unwrap(),
172 id_member,
173 },
174 );
175 }
176
177 stb_nodes
178}
179
180fn extract_stb_axes(stb_model_node: roxmltree::Node) -> StbAxes {
181 let stb_axes_node = extract_node("StbAxes", stb_model_node).unwrap();
182
183 let mut stb_axes = StbAxes::new();
184
185 for node in stb_axes_node.children().filter(|n| n.is_element()) {
186 let stb_node_id_list_node = extract_node("StbNodeid_List", node).unwrap();
187
188 let mut stb_node_id_list = Vec::new();
189
190 for children in stb_node_id_list_node.children().filter(|n| n.is_element()) {
191 let id = parse_attribute("id", children).unwrap();
192 stb_node_id_list.push(StbNodeId { id });
193 }
194
195 match node.tag_name().name() {
196 "StbX_Axis" => {
197 stb_axes.stb_x_axis_list.push(StbXAxis {
198 id: parse_attribute("id", node).unwrap(),
199 name: parse_attribute("name", node).unwrap(),
200 distance: parse_attribute("distance", node).unwrap(),
201 stb_node_id_list: StbNodeIdList {
202 children: stb_node_id_list,
203 },
204 });
205 }
206 "StbY_Axis" => {
207 stb_axes.stb_y_axis_list.push(StbYAxis {
208 id: parse_attribute("id", node).unwrap(),
209 name: parse_attribute("name", node).unwrap(),
210 distance: parse_attribute("distance", node).unwrap(),
211 stb_node_id_list: StbNodeIdList {
212 children: stb_node_id_list,
213 },
214 });
215 }
216 _ => {
217 panic!("Tag name {} is invalid.", node.tag_name().name());
218 }
219 }
220 }
221
222 stb_axes
223}
224
225fn extract_stb_stories(stb_model_node: roxmltree::Node) -> StbStories {
226 let stb_stories_node = extract_node("StbStories", stb_model_node).unwrap();
227
228 let mut stb_stories = StbStories::new();
229
230 for node in stb_stories_node.children().filter(|n| n.is_element()) {
231 let stb_node_id_list_node = extract_node("StbNodeid_List", node).unwrap();
232
233 let mut stb_node_id_list = Vec::new();
234
235 for children in stb_node_id_list_node.children().filter(|n| n.is_element()) {
236 let id = parse_attribute("id", children).unwrap();
237 stb_node_id_list.push(StbNodeId { id });
238 }
239
240 stb_stories.stb_story_list.push(StbStory {
241 id: parse_attribute("id", node).unwrap(),
242 name: parse_attribute("name", node).unwrap(),
243 height: parse_attribute("height", node).unwrap(),
244 kind: StbStoryKind::from_str(node.attribute("kind").unwrap()).unwrap(),
245 concrete_strength: node.attribute("concrete_strength").unwrap().to_string(),
246 stb_node_id_list: StbNodeIdList {
247 children: stb_node_id_list,
248 },
249 });
250 }
251
252 stb_stories
253}
254
255fn extract_stb_members(stb_model_node: roxmltree::Node) -> StbMembers {
256 let stb_members_node = extract_node("StbMembers", stb_model_node).unwrap();
257
258 let stb_columns = extract_stb_columns(stb_members_node);
259 let stb_posts = extract_stb_posts(stb_members_node);
260 let stb_girders = extract_stb_girders(stb_members_node);
261 let stb_beams = extract_stb_beams(stb_members_node);
262 let stb_braces = extract_stb_braces(stb_members_node);
263 let stb_slabs = extract_stb_slabs(stb_members_node);
264
265 StbMembers {
266 stb_columns,
267 stb_posts,
268 stb_girders,
269 stb_beams,
270 stb_braces,
271 stb_slabs,
272 }
273}
274
275fn extract_stb_columns(stb_members_node: roxmltree::Node) -> StbColumns {
276 let stb_columns_node = extract_node("StbColumns", stb_members_node).unwrap();
277
278 let mut stb_column_list: Vec<StbColumn> = Vec::new();
279
280 for node in stb_columns_node.children().filter(|n| n.is_element()) {
281 stb_column_list.push(StbColumn {
282 id: parse_attribute("id", node).unwrap(),
283 name: node.attribute("name").unwrap().to_string(),
284 id_node_bottom: parse_attribute("idNode_bottom", node).unwrap(),
285 id_node_top: parse_attribute("idNode_top", node).unwrap(),
286 rotate: parse_attribute("rotate", node).unwrap(),
287 id_section: parse_attribute("id_section", node).unwrap(),
288 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
289 offset_x: parse_attribute("offset_X", node).unwrap(),
290 offset_y: parse_attribute("offset_Y", node).unwrap(),
291 condition_bottom: parse_enum_attribute("condition_bottom", node).unwrap(),
292 condition_top: parse_enum_attribute("condition_top", node).unwrap(),
293 });
294 }
295
296 StbColumns { stb_column_list }
297}
298
299fn extract_stb_posts(stb_members_node: roxmltree::Node) -> StbPosts {
300 let stb_posts_node = extract_node("StbPosts", stb_members_node).unwrap();
301
302 let mut stb_post_list: Vec<StbPost> = Vec::new();
303
304 for node in stb_posts_node.children().filter(|n| n.is_element()) {
305 stb_post_list.push(StbPost {
306 id: parse_attribute("id", node).unwrap(),
307 name: node.attribute("name").unwrap().to_string(),
308 id_node_bottom: parse_attribute("idNode_bottom", node).unwrap(),
309 id_node_top: parse_attribute("idNode_top", node).unwrap(),
310 rotate: parse_attribute("rotate", node).unwrap(),
311 id_section: parse_attribute("id_section", node).unwrap(),
312 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
313 offset_x: parse_attribute("offset_X", node).unwrap(),
314 offset_y: parse_attribute("offset_Y", node).unwrap(),
315 offset_bottom_x: parse_attribute("offset_bottom_X", node).unwrap(),
316 offset_bottom_y: parse_attribute("offset_bottom_Y", node).unwrap(),
317 offset_bottom_z: parse_attribute("offset_bottom_Z", node).unwrap(),
318 offset_top_x: parse_attribute("offset_top_X", node).unwrap(),
319 offset_top_y: parse_attribute("offset_top_Y", node).unwrap(),
320 offset_top_z: parse_attribute("offset_top_Z", node).unwrap(),
321 condition_bottom: parse_enum_attribute("condition_bottom", node).unwrap(),
322 condition_top: parse_enum_attribute("condition_top", node).unwrap(),
323 });
324 }
325
326 StbPosts { stb_post_list }
327}
328
329fn extract_stb_girders(stb_members_node: roxmltree::Node) -> StbGirders {
330 let stb_girders_node = extract_node("StbGirders", stb_members_node).unwrap();
331
332 let mut stb_girder_list: Vec<StbGirder> = Vec::new();
333
334 for node in stb_girders_node.children().filter(|n| n.is_element()) {
335 stb_girder_list.push(StbGirder {
336 id: parse_attribute("id", node).unwrap(),
337 name: node.attribute("name").unwrap().to_string(),
338 id_node_start: parse_attribute("idNode_start", node).unwrap(),
339 id_node_end: parse_attribute("idNode_end", node).unwrap(),
340 rotate: parse_attribute("rotate", node).unwrap(),
341 id_section: parse_attribute("id_section", node).unwrap(),
342 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
343 is_foundation: parse_attribute("isFoundation", node).unwrap(),
344 offset: parse_attribute("offset", node).unwrap(),
345 level: parse_attribute("level", node).unwrap(),
346 type_haunch_h: match node.attribute("type_haunch_H") {
347 Some(s) => Some(HaunchType::from_str(s).unwrap()),
348 None => None,
349 },
350 });
351 }
352
353 StbGirders { stb_girder_list }
354}
355
356fn extract_stb_beams(stb_members_node: roxmltree::Node) -> StbBeams {
357 let stb_beams_node = extract_node("StbBeams", stb_members_node).unwrap();
358
359 let mut stb_beam_list: Vec<StbBeam> = Vec::new();
360
361 for node in stb_beams_node.children().filter(|n| n.is_element()) {
362 stb_beam_list.push(StbBeam {
363 id: parse_attribute("id", node).unwrap(),
364 name: node.attribute("name").unwrap().to_string(),
365 id_node_start: parse_attribute("idNode_start", node).unwrap(),
366 id_node_end: parse_attribute("idNode_end", node).unwrap(),
367 rotate: parse_attribute("rotate", node).unwrap(),
368 id_section: parse_attribute("id_section", node).unwrap(),
369 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
370 is_foundation: parse_attribute("isFoundation", node).unwrap(),
371 offset: parse_attribute("offset", node).unwrap(),
372 level: parse_attribute("level", node).unwrap(),
373 });
374 }
375
376 StbBeams { stb_beam_list }
377}
378
379fn extract_stb_braces(stb_members_node: roxmltree::Node) -> StbBraces {
380 let stb_braces_node = extract_node("StbBraces", stb_members_node).unwrap();
381
382 let mut stb_brace_list: Vec<StbBrace> = Vec::new();
383
384 for node in stb_braces_node.children().filter(|n| n.is_element()) {
385 stb_brace_list.push(StbBrace {
386 id: parse_attribute("id", node).unwrap(),
387 name: node.attribute("name").unwrap().to_string(),
388 id_node_start: parse_attribute("idNode_start", node).unwrap(),
389 id_node_end: parse_attribute("idNode_end", node).unwrap(),
390 rotate: parse_attribute("rotate", node).unwrap(),
391 id_section: parse_attribute("id_section", node).unwrap(),
392 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
393 offset_start_x: parse_attribute("offset_start_X", node).unwrap(),
394 offset_start_y: parse_attribute("offset_start_Y", node).unwrap(),
395 offset_start_z: parse_attribute("offset_start_Z", node).unwrap(),
396 offset_end_x: parse_attribute("offset_end_X", node).unwrap(),
397 offset_end_y: parse_attribute("offset_end_Y", node).unwrap(),
398 offset_end_z: parse_attribute("offset_end_Z", node).unwrap(),
399 condition_start: parse_enum_attribute("condition_start", node).unwrap(),
400 condition_end: parse_enum_attribute("condition_end", node).unwrap(),
401 });
402 }
403
404 StbBraces { stb_brace_list }
405}
406
407fn extract_stb_slabs(stb_members_node: roxmltree::Node) -> StbSlabs {
408 let stb_slabs_node = extract_node("StbSlabs", stb_members_node).unwrap();
409
410 let mut stb_slab_list: Vec<StbSlab> = Vec::new();
411
412 for node in stb_slabs_node.children().filter(|n| n.is_element()) {
413 stb_slab_list.push(StbSlab {
414 id: parse_attribute("id", node).unwrap(),
415 name: node.attribute("name").unwrap().to_string(),
416 id_section: parse_attribute("id_section", node).unwrap(),
417 kind_structure: parse_enum_attribute("kind_structure", node).unwrap(),
418 kind_slab: parse_enum_attribute("kind_slab", node).unwrap(),
419 level: parse_attribute("level", node).unwrap(),
420 is_foundation: parse_attribute("isFoundation", node).unwrap(),
421 });
422 }
423
424 StbSlabs { stb_slab_list }
425}
426
427fn extract_stb_sections(stb_model_node: roxmltree::Node) -> StbSections {
428 let stb_sections_node = extract_node("StbSections", stb_model_node).unwrap();
429
430 let mut stb_sections = StbSections::new();
431
432 for node in stb_sections_node.children().filter(|n| n.is_element()) {
433 let tag_name = node.tag_name().name();
434
435 match tag_name {
436 "StbSecColumn_RC" => unimplemented_panic(tag_name),
437 "StbSecColumn_S" => stb_sections
438 .children
439 .push(Box::new(extract_stb_sec_column_s(node))),
440 "StbSecColumn_SRC" => unimplemented_panic(tag_name),
441 "StbSecColumn_CFT" => unimplemented_panic(tag_name),
442 "StbSecBeam_RC" => stb_sections
443 .children
444 .push(Box::new(extract_stb_sec_beam_rc(node))),
445 "StbSecBeam_S" => stb_sections
446 .children
447 .push(Box::new(extract_stb_sec_beam_s(node))),
448 "StbSecBeam_SRC" => unimplemented_panic(tag_name),
449 "StbSecBrace_S" => stb_sections
450 .children
451 .push(Box::new(extract_stb_sec_brace_s(node))),
452 "StbSecSlab_RC" => stb_sections
453 .children
454 .push(Box::new(extract_stb_sec_slab_rc(node))),
455 "StbSecSlabDeck" => unimplemented_panic(tag_name),
456 "StbSecSlabPrecast" => unimplemented_panic(tag_name),
457 "StbSecWall_RC" => unimplemented_panic(tag_name),
458 "StbSecFoundation_RC" => unimplemented_panic(tag_name),
459 "StbSecPile_RC" => unimplemented_panic(tag_name),
460 "StbSecPile_S" => unimplemented_panic(tag_name),
461 "StbSecPileProduct" => unimplemented_panic(tag_name),
462 "StbSecOpen_RC" => unimplemented_panic(tag_name),
463 "StbSecParapet_RC" => unimplemented_panic(tag_name),
464 "StbSecSteel" => stb_sections.stb_sec_steel = extract_stb_sec_steel(node),
465 "StbSecUndefined" => unimplemented_panic(tag_name),
466 _ => {
467 panic!("Tag name {} is invalid.", tag_name)
468 }
469 };
470 }
471
472 stb_sections
473}
474
475fn extract_stb_sec_column_s(node: roxmltree::Node) -> StbSecColumnS {
476 let stb_sec_steel_column_node = extract_node("StbSecSteelColumn", node).unwrap();
477 StbSecColumnS {
478 id: parse_attribute("id", node).unwrap(),
479 name: parse_attribute("name", node).unwrap(),
480 floor: parse_attribute("floor", node).unwrap(),
481 kind_column: parse_enum_attribute("kind_column", node).unwrap(),
482 direction: parse_attribute("direction", node).unwrap(),
483 base_type: parse_enum_attribute("base_type", node).unwrap(),
484 stb_sec_steel_column: StbSecSteelColumn {
485 pos: parse_enum_attribute("pos", stb_sec_steel_column_node).unwrap(),
486 shape: parse_enum_attribute("shape", stb_sec_steel_column_node).unwrap(),
487 strength_main: parse_attribute("strength_web", stb_sec_steel_column_node).unwrap(),
488 strength_web: parse_attribute("strength_web", stb_sec_steel_column_node).unwrap(),
489 },
490 }
491}
492
493fn extract_stb_sec_beam_rc(node: roxmltree::Node) -> StbSecBeamRC {
494 let stb_sec_figure_node = extract_node("StbSecFigure", node).unwrap();
495 let stb_sec_figure = extract_stb_sec_figure_beam(stb_sec_figure_node);
496
497 let stb_sec_bar_arrangement_node = extract_node("StbSecBar_Arrangement", node).unwrap();
498 let stb_sec_bar_arrangement = extract_stb_sec_bar_arrangement(stb_sec_bar_arrangement_node);
499
500 StbSecBeamRC {
501 id: parse_attribute("id", node).unwrap(),
502 name: parse_attribute("name", node).unwrap(),
503 floor: parse_attribute("name", node).unwrap(),
504 kind_beam: parse_enum_attribute("kind_beam", node).unwrap(),
505 is_foundation: parse_attribute("isFoundation", node).unwrap(),
506 is_canti: parse_attribute("isCanti", node).unwrap(),
507 d_reinforcement_main: parse_attribute("D_reinforcement_main", node).unwrap(),
508 d_stirrup: parse_attribute("D_stirrup", node).unwrap(),
509 d_reinforcement_web: parse_attribute("D_reinforcement_web", node).unwrap(),
510 d_bar_spacing: parse_attribute("D_bar_spacing", node).unwrap(),
511 strength_concrete: match node.attribute("strength_concrete") {
512 Some(s) => Some(s.to_string()),
513 None => None,
514 },
515 strength_reinforcement_main: parse_attribute("strength_reinforcement_main", node).unwrap(),
516 strength_reinforcement_2nd_main: match node.attribute("strength_reinforcement_2nd_main") {
517 Some(s) => Some(s.to_string()),
518 None => None,
519 },
520 strength_stirrup: parse_attribute("strength_stirrup", node).unwrap(),
521 strength_reinforcement_web: parse_attribute("strength_reinforcement_web", node).unwrap(),
522 strength_bar_spacing: parse_attribute("strength_bar_spacing", node).unwrap(),
523 depth_cover_left: match node.attribute("depth_cover_left") {
524 Some(s) => Some(s.parse().unwrap()),
525 None => None,
526 },
527 depth_cover_right: match node.attribute("depth_cover_right") {
528 Some(s) => Some(s.parse().unwrap()),
529 None => None,
530 },
531 depth_cover_top: match node.attribute("depth_cover_top") {
532 Some(s) => Some(s.parse().unwrap()),
533 None => None,
534 },
535 depth_cover_bottom: match node.attribute("depth_cover_bottom") {
536 Some(s) => Some(s.parse().unwrap()),
537 None => None,
538 },
539 stb_sec_figure,
540 stb_sec_bar_arrangement,
541 }
542}
543
544fn extract_stb_sec_bar_arrangement(node: roxmltree::Node) -> StbSecBarArrangementBeam {
545 let stb_sec_beam_start_center_end_section_list = match extract_node("", node) {
546 Some(_) => {
547 let mut list = Vec::new();
548 for children in node.children().filter(|n| n.is_element()) {
549 list.push(extract_stb_sec_beam_start_center_end_section(children));
550 }
551 Some(list)
552 }
553 None => None,
554 };
555
556 let stb_sec_beam_same_section = match extract_node("", node) {
557 Some(n) => Some(extract_stb_sec_beam_same_section(n)),
558 None => None,
559 };
560
561 StbSecBarArrangementBeam {
562 stb_sec_beam_start_center_end_section_list,
563 stb_sec_beam_same_section,
564 }
565}
566
567fn extract_stb_sec_beam_start_center_end_section(
568 node: roxmltree::Node,
569) -> StbSecBeamStartCenterEndSection {
570 StbSecBeamStartCenterEndSection {
571 pos: parse_enum_attribute("pos", node).unwrap(),
572 count_main_top_1st: parse_attribute("count_main_top_1st", node).unwrap(),
573 count_main_bottom_1st: parse_attribute("count_main_bottom_1st", node).unwrap(),
574 count_stirrup: parse_attribute("count_stirrup", node).unwrap(),
575 pitch_stirrup: parse_attribute("pitch_stirrup", node).unwrap(),
576 count_web: parse_attribute("count_web", node).unwrap(),
577 count_bar_spacing: parse_attribute("count_bar_spacing", node).unwrap(),
578 pitch_bar_spacing: parse_attribute("pitch_bar_spacing", node).unwrap(),
579 }
580}
581
582fn extract_stb_sec_beam_same_section(node: roxmltree::Node) -> StbSecBeamSameSection {
583 StbSecBeamSameSection {
584 count_main_top_1st: parse_attribute("count_main_top_1st", node).unwrap(),
585 count_main_bottom_1st: parse_attribute("count_main_bottom_1st", node).unwrap(),
586 count_stirrup: parse_attribute("count_stirrup", node).unwrap(),
587 pitch_stirrup: parse_attribute("pitch_stirrup", node).unwrap(),
588 count_web: parse_attribute("count_web", node).unwrap(),
589 count_bar_spacing: parse_attribute("count_bar_spacing", node).unwrap(),
590 pitch_bar_spacing: parse_attribute("pitch_bar_spacing", node).unwrap(),
591 }
592}
593
594fn extract_stb_sec_figure_beam(node: roxmltree::Node) -> StbSecFigureBeam {
595 let stb_sec_haunch = match extract_node("StbSecHaunch", node) {
596 Some(n) => Some(extract_stb_sec_haunch(n)),
597 None => None,
598 };
599
600 let stb_sec_straight = match extract_node("StbSecStraight", node) {
601 Some(n) => Some(extract_stb_sec_straight(n)),
602 None => None,
603 };
604
605 StbSecFigureBeam {
606 stb_sec_haunch,
607 stb_sec_straight,
608 }
609}
610
611fn extract_stb_sec_haunch(node: roxmltree::Node) -> StbSecHaunch {
612 StbSecHaunch {
613 width_start: parse_attribute("width_start", node).unwrap(),
614 depth_start: parse_attribute("depth_start", node).unwrap(),
615 width_center: parse_attribute("width_center", node).unwrap(),
616 depth_center: parse_attribute("depth_center", node).unwrap(),
617 width_end: parse_attribute("width_end", node).unwrap(),
618 depth_end: parse_attribute("depth_end", node).unwrap(),
619 }
620}
621
622fn extract_stb_sec_straight(node: roxmltree::Node) -> StbSecStraightBeam {
623 StbSecStraightBeam {
624 depth: parse_attribute("depth", node).unwrap(),
625 }
626}
627
628fn extract_stb_sec_beam_s(node: roxmltree::Node) -> StbSecBeamS {
629 let stb_sec_steel_beam_node = extract_node("StbSecSteelBeam", node).unwrap();
630 let stb_sec_steel_beam = extract_stb_sec_steel_beam(stb_sec_steel_beam_node);
631
632 StbSecBeamS {
633 id: parse_attribute("id", node).unwrap(),
634 name: parse_attribute("name", node).unwrap(),
635 floor: parse_attribute("floor", node).unwrap(),
636 kind_beam: parse_enum_attribute("kind_beam", node).unwrap(),
637 is_canti: parse_attribute("isCanti", node).unwrap(),
638 stb_sec_steel_beam,
639 }
640}
641
642fn extract_stb_sec_steel_beam(node: roxmltree::Node) -> StbSecSteelBeam {
643 StbSecSteelBeam {
644 pos: parse_enum_attribute("pos", node).unwrap(),
645 shape: parse_attribute("shape", node).unwrap(),
646 strength_main: parse_attribute("strength_main", node).unwrap(),
647 strength_web: parse_attribute("strength_web", node).unwrap(),
648 }
649}
650
651fn extract_stb_sec_brace_s(node: roxmltree::Node) -> StbSecBraceS {
652 let stb_sec_steel_brace_node = extract_node("StbSecSteelBrace", node).unwrap();
653 let stb_sec_steel_brace = StbSecSteelBrace {
654 pos: parse_enum_attribute("pos", stb_sec_steel_brace_node).unwrap(),
655 shape: parse_attribute("shape", stb_sec_steel_brace_node).unwrap(),
656 strength_main: parse_attribute("strength_main", stb_sec_steel_brace_node).unwrap(),
657 strength_web: parse_attribute("strength_web", stb_sec_steel_brace_node).unwrap(),
658 };
659
660 StbSecBraceS {
661 id: parse_attribute("id", node).unwrap(),
662 name: parse_attribute("name", node).unwrap(),
663 floor: parse_attribute("floor", node).unwrap(),
664 kind_brace: parse_enum_attribute("kind_brace", node).unwrap(),
665 stb_sec_steel_brace,
666 }
667}
668
669fn extract_stb_sec_slab_rc(node: roxmltree::Node) -> StbSecSlabRC {
670 let stb_sec_figure_node = extract_node("StbSecFigure", node).unwrap();
671 let stb_sec_straight_node = extract_node("StbSecStraight", stb_sec_figure_node).unwrap();
672 let stb_sec_straight = StbSecStraightSlab {
673 depth: parse_attribute("depth", stb_sec_straight_node).unwrap(),
674 };
675 let stb_sec_figure = StbSecFigureSlab { stb_sec_straight };
676
677 let stb_sec_bar_arrangement_node = extract_node("StbSecBar_Arrangement", node).unwrap();
678 let mut stb_sec_1way_slab_1_list = Vec::new();
679
680 for children in stb_sec_bar_arrangement_node
681 .children()
682 .filter(|n| n.is_element())
683 {
684 stb_sec_1way_slab_1_list.push(StbSec1WaySlab1 {
685 pos: parse_enum_attribute("pos", children).unwrap(),
686 strength: parse_attribute("strength", children).unwrap(),
687 d: parse_attribute("D", children).unwrap(),
688 pitch: parse_attribute("pitch", children).unwrap(),
689 });
690 }
691
692 let stb_sec_bar_arrangement = StbSecBarArrangementSlab {
693 stb_sec_1way_slab_1_list,
694 };
695
696 StbSecSlabRC {
697 id: parse_attribute("id", node).unwrap(),
698 name: parse_attribute("name", node).unwrap(),
699 is_foundation: parse_attribute("isFoundation", node).unwrap(),
700 is_canti: parse_attribute("isCanti", node).unwrap(),
701 strength_concrete: parse_attribute("strength_concrete", node).unwrap(),
702 stb_sec_figure,
703 stb_sec_bar_arrangement,
704 }
705}
706
707fn extract_stb_sec_steel(stb_sec_steel_node: roxmltree::Node) -> StbSecSteel {
708 let mut stb_sec_steel = StbSecSteel::new();
709
710 for node in stb_sec_steel_node.children().filter(|n| n.is_element()) {
711 let tag_name = node.tag_name().name();
712 match tag_name {
713 "StbSecRoll-H" => stb_sec_steel
714 .children
715 .push(Box::new(extract_stb_sec_roll_h(node))),
716 "StbSecBuild-H" => stb_sec_steel
717 .children
718 .push(Box::new(extract_stb_sec_build_h(node))),
719 "StbSecRoll-BOX" => stb_sec_steel
720 .children
721 .push(Box::new(extract_stb_sec_roll_box(node))),
722 "StbSecBuild-BOX" => stb_sec_steel
723 .children
724 .push(Box::new(extract_stb_sec_build_box(node))),
725 "StbSecPipe" => stb_sec_steel
726 .children
727 .push(Box::new(extract_stb_sec_pipe(node))),
728 "StbSecRoll-T" => unimplemented_panic(tag_name),
729 "StbSecRoll-C" => unimplemented_panic(tag_name),
730 "StbSecRoll-L" => stb_sec_steel
731 .children
732 .push(Box::new(extract_stb_sec_roll_l(node))),
733 "StbSecLipC" => unimplemented_panic(tag_name),
734 "StbSecFlatBar" => unimplemented_panic(tag_name),
735 "StbSecRoundBar" => unimplemented_panic(tag_name),
736 "StbSecSteelProduct" => unimplemented_panic(tag_name),
737 "StbSecSteelUndefined" => unimplemented_panic(tag_name),
738 _ => panic!("Tag name {} is invalid.", tag_name),
739 }
740 }
741
742 stb_sec_steel
743}
744
745fn extract_stb_sec_roll_h(node: roxmltree::Node) -> StbSecRollH {
746 StbSecRollH {
747 name: parse_attribute("name", node).unwrap(),
748 sec_type: parse_enum_attribute("type", node).unwrap(),
749 a: parse_attribute("A", node).unwrap(),
750 b: parse_attribute("B", node).unwrap(),
751 t1: parse_attribute("t1", node).unwrap(),
752 t2: parse_attribute("t2", node).unwrap(),
753 r: parse_attribute("r", node).unwrap(),
754 }
755}
756
757fn extract_stb_sec_build_h(node: roxmltree::Node) -> StbSecBuildH {
758 StbSecBuildH {
759 name: parse_attribute("name", node).unwrap(),
760 a: parse_attribute("A", node).unwrap(),
761 b: parse_attribute("B", node).unwrap(),
762 t1: parse_attribute("t1", node).unwrap(),
763 t2: parse_attribute("t2", node).unwrap(),
764 }
765}
766
767fn extract_stb_sec_roll_box(node: roxmltree::Node) -> StbSecRollBox {
768 StbSecRollBox {
769 name: parse_attribute("name", node).unwrap(),
770 sec_type: parse_enum_attribute("type", node).unwrap(),
771 a: parse_attribute("A", node).unwrap(),
772 b: parse_attribute("B", node).unwrap(),
773 t: parse_attribute("t", node).unwrap(),
774 r: parse_attribute("R", node).unwrap(),
775 }
776}
777
778fn extract_stb_sec_build_box(node: roxmltree::Node) -> StbSecBuildBox {
779 StbSecBuildBox {
780 name: parse_attribute("name", node).unwrap(),
781 a: parse_attribute("A", node).unwrap(),
782 b: parse_attribute("B", node).unwrap(),
783 t1: parse_attribute("t1", node).unwrap(),
784 t2: parse_attribute("t2", node).unwrap(),
785 }
786}
787
788fn extract_stb_sec_pipe(node: roxmltree::Node) -> StbSecPipe {
789 StbSecPipe {
790 name: parse_attribute("name", node).unwrap(),
791 d: parse_attribute("D", node).unwrap(),
792 t: parse_attribute("t", node).unwrap(),
793 }
794}
795
796fn extract_stb_sec_roll_l(node: roxmltree::Node) -> StbSecRollL {
797 StbSecRollL {
798 name: parse_attribute("name", node).unwrap(),
799 sec_type: parse_enum_attribute("type", node).unwrap(),
800 a: parse_attribute("A", node).unwrap(),
801 b: parse_attribute("B", node).unwrap(),
802 t1: parse_attribute("t1", node).unwrap(),
803 t2: parse_attribute("t2", node).unwrap(),
804 r1: parse_attribute("r1", node).unwrap(),
805 r2: parse_attribute("r2", node).unwrap(),
806 side: parse_attribute("side", node).unwrap(),
807 }
808}
809
810pub fn extract_stb_extensions(root_node: roxmltree::Node) -> StbExtensions {
811 let stb_extensions_node = extract_node("StbExtensions", root_node).unwrap();
812
813 let mut stb_extension_list = Vec::new();
814
815 for node in stb_extensions_node.children().filter(|n| n.is_element()) {
816 stb_extension_list.push(StbExtension {
817 identifier: parse_attribute("identifier", node).unwrap(),
818 description: parse_attribute("description", node).unwrap(),
819 });
820 }
821
822 StbExtensions { stb_extension_list }
823}
824
825fn parse_attribute<T: FromStr>(
826 name: &str,
827 node: roxmltree::Node,
828) -> Result<T, <T as FromStr>::Err> {
829 node.attribute(name).unwrap().to_lowercase().parse::<T>()
830}
831
832fn parse_enum_attribute<T: FromStr>(
833 name: &str,
834 node: roxmltree::Node,
835) -> Result<T, <T as FromStr>::Err> {
836 T::from_str(node.attribute(name).unwrap())
837}
838
839fn unimplemented_panic(what: &str) {
840 panic!("{} is unimplemented!", what);
841}