use shared::Float; use std::fs; use std::io::{self, BufReader, Error, ErrorKind, Read}; use std::path::{Path, PathBuf}; use std::sync::OnceLock; static SEARCH_DIRECTORY: OnceLock = OnceLock::new(); fn set_search_directory(filename: &str) { let path = Path::new(filename); let dir = if path.is_dir() { path.to_path_buf() } else { path.parent().unwrap_or(Path::new("")).to_path_buf() }; let _ = SEARCH_DIRECTORY.set(dir); } pub fn resolve_filename(filename: &str) -> String { let search_directory = SEARCH_DIRECTORY .get() .map(|p| p.as_path()) .unwrap_or(Path::new("")); if search_directory.as_os_str().is_empty() || filename.is_empty() || Path::new(filename).is_absolute() { return filename.to_string(); } let filepath = search_directory.join(filename); if filepath.exists() { filepath .canonicalize() .unwrap_or_else(|_| filepath.to_path_buf()) .to_string_lossy() .to_string() } else { filename.to_string() } } pub fn read_float_file(filename: &str) -> io::Result> { let content = fs::read_to_string(filename)?; let mut values = Vec::new(); for (line_num, line) in content.lines().enumerate() { // Strip comments let cleaned = line.split('#').next().unwrap_or(""); for token in cleaned.split_whitespace() { match token.parse::() { Ok(val) => values.push(val), Err(e) => { return Err(Error::new( ErrorKind::InvalidData, format!( "Failed to parse float '{}' at line {}: {}", token, line_num + 1, e ), )); } } } } Ok(values) }