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:
parent
ac5d8e0c75
commit
f17dd5b89d
|
@ -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,22 +79,21 @@ 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> {
|
||||||
let (input, (q, r)) = delimited(
|
let (input, (q, r)) = delimited(
|
||||||
|
@ -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('.')));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue