lex-map_editor_std 0.2.0

standard types and parser for lex-map_editor
Documentation
//! standard map

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 validate() -> Result<&str, &str> {} //TODO
	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(); //this shouldn't fail
		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(())
	}
}