//! Module containing the raw map data version of the map. use super::{IconData, Map, PolygonRoomData, RectRoomData, WallData}; use ron::de::from_reader; use ron::ser::{to_string_pretty, PrettyConfig}; use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::{self, Write}; use std::path::Path; /// The serialisable and deserialisable parts of the map. This can be created to get a version of the /// map which is persistifiable or sendable/receivable without data overhead or data that might make /// it easily corruptable. #[derive(Serialize, Deserialize)] pub struct MapData { pub(super) rect_rooms: Vec, pub(super) polygon_rooms: Vec, pub(super) walls: Vec, pub(super) icons: Vec, } impl MapData { /// Create a serialisable map data type from the data elements contained in a map. pub fn new( rect_rooms: Vec, polygon_rooms: Vec, walls: Vec, icons: Vec, ) -> Self { Self { rect_rooms, polygon_rooms, walls, icons, } } /// Creates a data struct from the Map. It is important to note, that this data element is not /// bound to the Map in any way after this, so changing anything won't change anything in the map. /// It is useful however to for instance serialize this map without extra rendering information /// included. pub fn extract_data(map: &Map) -> Self { Self { rect_rooms: map .rect_rooms() .iter() .map(|r| (r as &RectRoomData).clone()) .collect(), polygon_rooms: map .polygon_rooms() .iter() .map(|p| (p as &PolygonRoomData).clone()) .collect(), walls: map .walls() .iter() .map(|w| (w as &WallData).clone()) .collect(), icons: map .icons() .iter() .map(|i| (i as &IconData).clone()) .collect(), } } /// Load the map data from a file. Fails if the file does not exist or cannot be correctly parsed. pub fn load_from_file>(&mut self, path: P) -> io::Result { let file = File::open(&path)?; let data: Self = match from_reader(file) { Ok(data) => data, Err(err) => { return Err(io::Error::new(io::ErrorKind::InvalidData, err)); } }; Ok(data) } /// Write the map data to the file located at `path`. If the file already exists, it will be /// overwritten. If the write fails, an IO-Error is returned. pub fn write_to_file>(&self, path: P) -> io::Result<()> { let mut file = File::create(&path)?; let pretty_conf = PrettyConfig::new() .with_depth_limit(4) .with_decimal_floats(true) .with_separate_tuple_members(true) .with_indentor("\t".to_owned()); let string = match to_string_pretty(&self, pretty_conf) { Ok(string) => string, Err(err) => { return Err(io::Error::new(io::ErrorKind::InvalidInput, err)); } }; file.write_all(&string.as_bytes()) } }