use crate::types::*;
#[derive(Debug)]
#[derive(PartialEq)]
pub struct Map{
pub version: String,
pub name: String,
pub unit: u32,
pub size_x: u32,
pub size_y: u32,
pub blocks: Vec<Block>,
pub objects: Vec<Object>,
pub entities: Vec<Entity>,
}
impl Map{
pub fn new(name: &str, unit: u32, size_x: u32, size_y: u32) -> Self {
Self{
version: env!("CARGO_PKG_VERSION").to_owned(),
name: name.to_owned(),
unit,
size_x,
size_y,
blocks: Vec::new(),
objects: Vec::new(),
entities: Vec::new(),
}
}
pub fn new_empty() -> Self {
Self {
version: env!("CARGO_PKG_VERSION").to_owned(),
name: "none".to_owned(),
unit: 16,
size_x: 2048,
size_y: 1024,
blocks: Vec::new(),
objects: Vec::new(),
entities: Vec::new(),
}
}
pub fn to_string(&self) -> String {
["map,version,",&self.version,"\n",
"map,name,",&self.name,"\n",
"map,unit,",&self.unit.to_string(),"\n",
"map,size,",&self.size_x.to_string(),",",&self.size_y.to_string(),"\n",
].concat()
}
pub fn from_file(file: &mut std::fs::File) -> Result<Self, &str> {
use std::io::Read;
let mut tmp = Self::new_empty();
let mut content: String = String::new();
file.read_to_string(&mut content).unwrap(); let mut content = content.lines();
'parsing: loop {
let data_line = match content.next() {
Some(d) => d,
None => break 'parsing,
};
let data: Vec<&str> = data_line.split(',').collect();
match data[0] {
"map" => match data[1] {
"version" => tmp.version = data[2].to_owned(),
"name" => tmp.name = data[2].to_owned(),
"unit" => tmp.unit = match data[2].parse() {
Ok(v) => v,
Err(..) => return Err("invalid map.unit")
},
"size" => {
if !(data.len() > 3) {return Err("insuficient size data")};
tmp.size_x = match data[2].parse() {
Ok(v) => v,
Err(..) => return Err("invalid map.size_x")
};
tmp.size_y = match data[3].parse() {
Ok(v) => v,
Err(..) => return Err("invalid map.size_y")
};
},
_ => {}
}
"block" => tmp.blocks.push(match Block::from_str(&data_line) {
Ok(b) => b,
Err(..) => return Err("invalid block")
}),
"object" => tmp.objects.push(match Object::from_str(&data_line) {
Ok(o) => o,
Err(..) => return Err("invalid object")
}),
"entity" => tmp.entities.push(match Entity::from_str(&data_line) {
Ok(e) => e,
Err(..) => return Err("invalid entity")
}),
_ => {}
}
}
Ok(tmp)
}
pub fn to_file(&self, file: &mut std::fs::File) -> Result<(), &str> {
use std::io::Write;
if let Err(..) = writeln!(file, "{}", self.to_string()) {
return Err("couldn't write map");
}
for block in self.blocks.iter(){
if let Err(..) = writeln!(file, "{}", block.to_string()) {
return Err("couldn't write block");
}
}
for object in self.objects.iter(){
if let Err(..) = writeln!(file, "{}", object.to_string()) {
return Err("couldn't write object");
}
}
for entity in self.entities.iter(){
if let Err(..) = writeln!(file, "{}", entity.to_string()) {
return Err("couldn't write entity");
}
}
Ok(())
}
}