#![allow(clippy::tabs_in_doc_comments)]
use crate::map2d::MovingAiMap;
use crate::map2d::SceneRecord;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::path;
pub fn parse_map_file(path: &path::Path) -> io::Result<MovingAiMap> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
parse_map(&contents)
}
pub fn parse_map(contents: &str) -> io::Result<MovingAiMap> {
let mut height: usize = 0;
let mut width: usize = 0;
let mut map_type = String::from("empty");
let mut map: Vec<char> = Vec::new();
let mut parse_map = false;
for line in contents.lines() {
if parse_map {
map.extend(line.chars());
continue;
}
if line.trim() == "map" {
parse_map = true;
} else {
let mut parts = line.split_whitespace();
if let (Some(key), Some(value)) = (parts.next(), parts.next()) {
if parts.next().is_none() {
match key {
"type" => map_type = value.to_string(),
"height" => {
height = value.parse::<usize>().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
"Error parsing map height.",
)
})?
}
"width" => {
width = value.parse::<usize>().map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
"Error parsing map width.",
)
})?
}
_ => {}
}
}
}
}
}
if height == 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Map height is missing or zero.",
));
}
if width == 0 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"Map width is missing or zero.",
));
}
MovingAiMap::new(map_type, height, width, map)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))
}
pub fn parse_scen_file(path: &path::Path) -> io::Result<Vec<SceneRecord>> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
parse_scen(&contents)
}
pub fn parse_scen(contents: &str) -> io::Result<Vec<SceneRecord>> {
let mut table: Vec<SceneRecord> = Vec::new();
for line in contents.lines() {
if line.starts_with("version") {
continue;
}
if line.is_empty() {
continue;
}
let record: Vec<&str> = line.split('\t').collect();
if record.len() < 9 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Expected 9 fields in scene record, found {}", record.len()),
));
}
table.push(SceneRecord {
bucket: record[0].parse::<u32>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing bucket size.")
})?,
map_file: String::from(record[1]),
map_width: record[2].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing map width.")
})?,
map_height: record[3].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing map height.")
})?,
start_pos: (
record[4].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing start x.")
})?,
record[5].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing start y.")
})?,
),
goal_pos: (
record[6].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing goal x")
})?,
record[7].parse::<usize>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing goal y")
})?,
),
optimal_length: record[8].parse::<f64>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "Error parsing optimal length.")
})?,
})
}
Ok(table)
}