lex_map_editor_std/
map.rs

1//! standard map
2
3use crate::types::*;
4
5#[derive(Debug)]
6#[derive(PartialEq)]
7pub struct Map{
8	pub version: String,
9	pub name: String,
10	pub unit: u32,
11	pub size_x: u32,
12	pub size_y: u32,
13	pub blocks: Vec<Block>,
14	pub objects: Vec<Object>,
15	pub entities: Vec<Entity>,
16}
17
18impl Map{
19	pub fn new(name: &str, unit: u32, size_x: u32, size_y: u32) -> Self {
20		Self{
21			version: env!("CARGO_PKG_VERSION").to_owned(),
22			name: name.to_owned(),
23			unit,
24			size_x,
25			size_y,
26			blocks: Vec::new(),
27			objects: Vec::new(),
28			entities: Vec::new(),
29		}
30	}
31	
32	pub fn new_empty() -> Self {
33		Self {
34			version: env!("CARGO_PKG_VERSION").to_owned(),
35			name: "none".to_owned(),
36			unit: 16,
37			size_x: 2048,
38			size_y: 1024,
39			blocks: Vec::new(),
40			objects: Vec::new(),
41			entities: Vec::new(),
42		}
43	}
44	
45	pub fn to_string(&self) -> String {
46		["map,version,",&self.version,"\n",
47		"map,name,",&self.name,"\n",
48		"map,unit,",&self.unit.to_string(),"\n",
49		"map,size,",&self.size_x.to_string(),",",&self.size_y.to_string(),"\n",
50		].concat()
51	}
52	
53	// pub fn validate() -> Result<&str, &str> {} //TODO
54	pub fn from_file(file: &mut std::fs::File) -> Result<Self, &str> {
55		use std::io::Read;
56		let mut tmp = Self::new_empty();
57		let mut content: String = String::new();
58		file.read_to_string(&mut content).unwrap(); //this shouldn't fail
59		let mut content = content.lines();
60		'parsing: loop {
61			let data_line = match content.next() {
62				Some(d) => d,
63				None => break 'parsing,
64			};
65			let data: Vec<&str> = data_line.split(',').collect();
66			match data[0] {
67				"map" => match data[1] {
68					"version" => tmp.version = data[2].to_owned(),
69					"name" => tmp.name = data[2].to_owned(),
70					"unit" => tmp.unit = match data[2].parse() {
71						Ok(v) => v,
72						Err(..) => return Err("invalid map.unit")
73					},
74					"size" => {
75						if !(data.len() > 3) {return Err("insuficient size data")};
76						tmp.size_x = match data[2].parse() {
77							Ok(v) => v,
78							Err(..) => return Err("invalid map.size_x")
79						};
80						tmp.size_y = match data[3].parse() {
81							Ok(v) => v,
82							Err(..) => return Err("invalid map.size_y")
83						};
84					},
85					_ => {}
86				}
87				"block" => tmp.blocks.push(match Block::from_str(&data_line) {
88					Ok(b) => b,
89					Err(..) => return Err("invalid block")
90				}),
91				"object" => tmp.objects.push(match Object::from_str(&data_line) {
92					Ok(o) => o,
93					Err(..) => return Err("invalid object")
94				}),
95				"entity" => tmp.entities.push(match Entity::from_str(&data_line) {
96					Ok(e) => e,
97					Err(..) => return Err("invalid entity")
98				}),
99				_ => {}
100			}
101		}
102		Ok(tmp)
103	}
104	
105	pub fn to_file(&self, file: &mut std::fs::File) -> Result<(), &str> {
106		use std::io::Write;
107		if let Err(..) = writeln!(file, "{}", self.to_string()) {
108			return Err("couldn't write map");
109		}
110    
111		for block in self.blocks.iter(){
112			if let Err(..) = writeln!(file, "{}", block.to_string()) {
113				return Err("couldn't write block");
114			}
115		}
116		for object in self.objects.iter(){
117			if let Err(..) = writeln!(file, "{}", object.to_string()) {
118				return Err("couldn't write object");
119			}
120		}
121		for entity in self.entities.iter(){
122			if let Err(..) = writeln!(file, "{}", entity.to_string()) {
123				return Err("couldn't write entity");
124			}
125		}
126		Ok(())
127	}
128}