Clean up the read and write operations

maps no longer need to be serializable. This allows for both a serializable form and a non-serializable form.
This commit is contained in:
Savanni D'Gerinel 2023-01-21 11:23:32 -05:00
parent ac5d8e0c75
commit f17dd5b89d
2 changed files with 44 additions and 40 deletions

View File

@ -10,7 +10,7 @@ Luminescent Dreams Tools is distributed in the hope that it will be useful, but
You should have received a copy of the GNU General Public License along with Luminescent Dreams Tools. If not, see <https://www.gnu.org/licenses/>. You should have received a copy of the GNU General Public License along with Luminescent Dreams Tools. If not, see <https://www.gnu.org/licenses/>.
*/ */
use crate::hex::AxialAddr; use crate::{hex::AxialAddr, Error};
use nom::{ use nom::{
bytes::complete::tag, bytes::complete::tag,
character::complete::alphanumeric1, character::complete::alphanumeric1,
@ -29,10 +29,7 @@ pub struct Map<A> {
cells: HashMap<AxialAddr, A>, cells: HashMap<AxialAddr, A>,
} }
impl<A: Default + From<String> + Clone> Map<A> impl<A: Default + Clone> Map<A> {
where
String: From<A>,
{
pub fn new_hexagonal(radius: usize) -> Map<A> { pub fn new_hexagonal(radius: usize) -> Map<A> {
let cells = vec![(AxialAddr::origin(), Default::default())] let cells = vec![(AxialAddr::origin(), Default::default())]
.into_iter() .into_iter()
@ -56,15 +53,22 @@ where
pub fn get(&self, addr: &AxialAddr) -> Option<&A> { pub fn get(&self, addr: &AxialAddr) -> Option<&A> {
self.cells.get(addr) self.cells.get(addr)
} }
}
// pub fn from_file(path: PathBuf) -> Map<A> {} pub fn read_file<A: Default + From<String>>(path: PathBuf) -> Result<Map<A>, Error> {
let data = std::fs::read_to_string(path)?;
Ok(parse_data(data.lines()))
}
pub fn to_file(&self, path: PathBuf) -> () {} pub fn write_file<A: Clone>(path: PathBuf, map: Map<A>) -> Result<(), Error>
where
String: From<A>,
{
std::fs::write(path, write_data(map).join("\n")).map_err(Error::from)
}
pub fn from_data(data: Vec<String>) -> Map<A> { fn parse_data<'a, A: Default + From<String>>(data: impl Iterator<Item = &'a str> + 'a) -> Map<A> {
fn parse_line<A: From<String>>( fn parse_line<A: From<String>>(input: &str) -> Result<(AxialAddr, A), nom::error::Error<&str>> {
input: &str,
) -> Result<(AxialAddr, A), nom::error::Error<&str>> {
fn parse<A: From<String>>(input: &str) -> IResult<&str, (AxialAddr, A)> { fn parse<A: From<String>>(input: &str) -> IResult<&str, (AxialAddr, A)> {
let (input, addr) = parse_address(input)?; let (input, addr) = parse_address(input)?;
let (input, value) = cell_value::<A>(input)?; let (input, value) = cell_value::<A>(input)?;
@ -75,21 +79,20 @@ where
} }
let cells = data let cells = data
.into_iter()
.map(|line| parse_line::<A>(&line).unwrap()) .map(|line| parse_line::<A>(&line).unwrap())
.collect::<Vec<(AxialAddr, A)>>(); .collect::<Vec<(AxialAddr, A)>>();
let cells = cells.into_iter().collect::<HashMap<AxialAddr, A>>(); let cells = cells.into_iter().collect::<HashMap<AxialAddr, A>>();
Map { cells } Map { cells }
} }
pub fn to_data(&self) -> Vec<String> { fn write_data<A: Clone>(map: Map<A>) -> Vec<String>
self.cells where
String: From<A>,
{
map.cells
.iter() .iter()
.map(|(addr, val)| { .map(|(addr, val)| format!("[{}, {}] {}", addr.q(), addr.r(), String::from(val.clone())))
format!("[{}, {}] {}", addr.q(), addr.r(), String::from(val.clone()))
})
.collect() .collect()
}
} }
fn parse_address(input: &str) -> IResult<&str, AxialAddr> { fn parse_address(input: &str) -> IResult<&str, AxialAddr> {
@ -163,7 +166,7 @@ mod test {
expected.insert("[0, -1] .".to_owned()); expected.insert("[0, -1] .".to_owned());
expected.insert("[1, -1] .".to_owned()); expected.insert("[1, -1] .".to_owned());
let map_rows = map.to_data(); let map_rows = write_data(map);
assert_eq!(map_rows.len(), expected.len()); assert_eq!(map_rows.len(), expected.len());
map_rows map_rows
.iter() .iter()
@ -182,12 +185,7 @@ mod test {
[-1, 0] . [-1, 0] .
[0, -1] . [0, -1] .
[1, -1] ."; [1, -1] .";
let map: Map<MapVal> = Map::from_data( let map: Map<MapVal> = parse_data(map_data.lines());
map_data
.lines()
.map(|l| l.to_owned())
.collect::<Vec<String>>(),
);
assert_eq!(map.get(&AxialAddr::new(0, 0)), Some(&MapVal('L'))); assert_eq!(map.get(&AxialAddr::new(0, 0)), Some(&MapVal('L')));
assert_eq!(map.get(&AxialAddr::new(1, 0)), Some(&MapVal('A'))); assert_eq!(map.get(&AxialAddr::new(1, 0)), Some(&MapVal('A')));
assert_eq!(map.get(&AxialAddr::new(0, 1)), Some(&MapVal('.'))); assert_eq!(map.get(&AxialAddr::new(0, 1)), Some(&MapVal('.')));

View File

@ -17,7 +17,13 @@ pub enum Error {
IO(std::io::Error), IO(std::io::Error),
} }
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Self {
Self::IO(err)
}
}
mod hex; mod hex;
mod hex_map; pub mod hex_map;
pub use hex::AxialAddr; pub use hex::AxialAddr;