mod ascii;
mod game_map;
mod image;
use crate::maze::grid::Grid;
use ::image::RgbImage;
use std::{fs::File, io::Write};
pub use self::image::Image;
use super::errors::MazeSaveError;
pub use ascii::{AsciiNarrow, AsciiBroad};
pub use game_map::GameMap;
pub trait Formatter<T>
where
T: Saveable,
{
fn format(&self, grid: &Grid) -> T;
}
pub trait Saveable {
fn save(&self, path: &str) -> Result<String, MazeSaveError>;
}
pub struct ImageWrapper(RgbImage);
impl ImageWrapper {
pub fn into_inner(self) -> RgbImage {
self.0
}
}
impl Saveable for ImageWrapper {
fn save(&self, path: &str) -> Result<String, MazeSaveError> {
if let Err(reason) = self.0.save(path) {
return Err(MazeSaveError {
reason: reason.to_string(),
});
}
Ok(format!("Maze was successfully saved as an image: {}", path))
}
}
pub struct StringWrapper(String);
impl StringWrapper {
pub fn into_inner(self) -> String {
self.0
}
}
impl Saveable for StringWrapper {
fn save(&self, path: &str) -> Result<String, MazeSaveError> {
let path = match std::env::current_dir() {
Err(why) => {
return Err(MazeSaveError {
reason: format!("Couldn't find path to current dir: {}", why),
})
}
Ok(dir) => dir.join(path),
};
let mut file = match File::create(&path) {
Err(why) => {
return Err(MazeSaveError {
reason: format!("Couldn't create {}: {}", path.display(), why),
})
}
Ok(file) => file,
};
match file.write_all(self.0.as_bytes()) {
Err(why) => Err(MazeSaveError {
reason: format!("Couldn't write to {}: {}", path.display(), why),
}),
Ok(_) => Ok(format!(
"Maze was successfully written to a file: {}",
path.display()
)),
}
}
}
#[cfg(test)]
mod tests {
use ::image::Rgb;
use super::*;
#[test]
fn into_inner_returns_inner_string() {
let wrapper = StringWrapper(String::from("Hello, Rust!"));
let inner = wrapper.into_inner();
assert_eq!(inner, "Hello, Rust!");
}
#[test]
fn into_inner_returns_inner_image() {
let img = RgbImage::from_pixel(2, 2, Rgb([255, 0, 0])); let wrapper = ImageWrapper(img.clone());
let inner = wrapper.into_inner();
assert_eq!(inner.dimensions(), (2, 2));
assert_eq!(inner.get_pixel(0, 0), &Rgb([255, 0, 0]));
}
}