hfss_fld/fld_file_data_structs/
fld_file_loader.rs1mod file_header_utils;
2
3use std::fs::File;
4use std::io::{prelude::BufRead, BufReader};
5use std::path::Path;
6use std::str::FromStr;
7
8pub use file_header_utils::{DataCoordinates, DataDimensionality};
9
10#[derive(Debug)]
11pub struct FileData {
12 pub file_name: String,
13 pub geo_points: Vec<[f64; 3]>,
14 pub fld_points: Vec<Vec<f64>>,
15 pub dimensionality: DataDimensionality,
16 pub coordinates: DataCoordinates,
17 pub num_points: usize,
18}
19
20impl FileData {
21 pub fn load_file(
22 file_path: String,
23 expected_field_data_size: usize,
24 ) -> Result<Self, std::io::Error> {
25 let os_file_path = Path::new(&file_path);
27 let file_name = retrieve_file_name(&os_file_path);
28 let file = File::open(os_file_path)?;
29
30 let file_reader = BufReader::new(file);
32
33 let mut geo_points = Vec::new();
34 let mut fld_points = Vec::new();
35
36 let mut dimensionality = DataDimensionality::new();
37 let mut coordinates = DataCoordinates::None;
38
39 assert!(
40 expected_field_data_size > 0,
41 "FileData cannot expect zero sized data!"
42 );
43
44 for (i, line) in file_reader.lines().enumerate() {
45 match line {
46 Ok(line_text) => {
47 match i {
48 0 => {
49 dimensionality = match DataDimensionality::from_file_header(&line_text)
51 {
52 Ok(data_dimensionality) => data_dimensionality,
53 Err(msg) => panic!(
54 "Problem Parsing Fld File: `{}` \n Err: {}",
55 file_name, msg
56 ),
57 };
58 let num_points = dimensionality.total_num_points();
59
60 geo_points.reserve(num_points);
62 fld_points.reserve(num_points);
63 }
64 1 => {
65 coordinates = match DataCoordinates::from_file_header(&line_text) {
67 Ok(data_coordinates) => data_coordinates,
68 Err(msg) => panic!(
69 "Problem Parsing Fld File: `{}` \n Err: {}",
70 file_name, msg
71 ),
72 };
73 }
74 _ => {
75 let mut line_geo_points = [0.0; 3];
77 let mut line_fld_points = Vec::with_capacity(expected_field_data_size);
78
79 let line_text_sections = line_text.split(" ");
81 for (s, section) in line_text_sections.enumerate() {
82 let tokens = section.split(' ');
84 for (t, token) in tokens.enumerate() {
85 if token == "" {
86 continue;
87 }
88 match f64::from_str(token) {
90 Ok(value) => match s {
92 0 => line_geo_points[t] = value,
93 1 => {
94 assert!(
95 t < expected_field_data_size,
96 "Unexpected token on line {} of {}",
97 i,
98 file_name
99 );
100 line_fld_points.push(value);
101 }
102 _ => {
103 panic!(
104 "Unexpected token on line {} of {}",
105 i, file_name
106 );
107 }
108 },
109 Err(msg) => panic!(
110 "Unable to parse value on line {} of {} as f64! \n {}",
111 i, file_name, msg
112 ),
113 }
114 }
115 }
116
117 geo_points.push(line_geo_points);
119 fld_points.push(line_fld_points);
120 }
121 }
122 }
123 Err(msg) => panic!("Unable to read line {} of {} \n {}", i, file_name, msg),
124 }
125 }
126
127 geo_points.shrink_to_fit();
128 fld_points.shrink_to_fit();
129
130 let num_points = geo_points.len();
131 assert_eq!(
132 num_points,
133 fld_points.len(),
134 "Problem Parsing Fld File: `{}` \n Inconsistent Number of geometric and data points!",
135 file_name
136 );
137
138 dark_yellow!("{} \t", num_points);
139 print!("Data Points successfully loaded from: ");
140 dark_grey_ln!("`{}`", file_name);
141
142 Ok(Self {
143 file_name,
144 geo_points,
145 fld_points,
146 dimensionality,
147 coordinates,
148 num_points,
149 })
150 }
151}
152
153fn retrieve_file_name(os_file_path: &Path) -> String {
154 let name = os_file_path.file_name();
155
156 match name {
157 Some(file_name) => file_name.to_string_lossy().into_owned(),
158 None => String::from("-UNNAMED FLD FILE-"),
159 }
160}