2021-07-22 05:59:25 +10:00
|
|
|
use serde::Deserialize;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::fs;
|
|
|
|
|
2021-07-22 07:46:22 +10:00
|
|
|
use crate::{Colour, TileSize};
|
2021-07-22 05:59:25 +10:00
|
|
|
|
2021-07-22 07:07:09 +10:00
|
|
|
pub(crate) fn parse(filename: &str) -> Box<dyn Config> {
|
2021-07-22 07:46:22 +10:00
|
|
|
let config_toml =
|
|
|
|
fs::read_to_string(filename).unwrap_or_else(|_| panic!("Failed to read file {}", filename));
|
|
|
|
|
2021-07-22 05:59:25 +10:00
|
|
|
let config: ConfigV1 = toml::from_str(&config_toml).expect("Failed to parse file");
|
|
|
|
|
|
|
|
if config.version != "1.0" {
|
2021-07-22 07:46:22 +10:00
|
|
|
panic!(
|
|
|
|
"Expected version of {} to be 1.0, got {}",
|
|
|
|
filename, config.version
|
|
|
|
);
|
2021-07-22 05:59:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
Box::new(config)
|
|
|
|
}
|
|
|
|
|
2021-07-22 07:07:09 +10:00
|
|
|
pub(crate) trait Config {
|
2021-07-22 05:59:25 +10:00
|
|
|
fn crate_prefix(&self) -> String;
|
|
|
|
fn images(&self) -> HashMap<String, &dyn Image>;
|
|
|
|
}
|
|
|
|
|
2021-07-22 07:07:09 +10:00
|
|
|
pub(crate) trait Image {
|
2021-07-22 05:59:25 +10:00
|
|
|
fn filename(&self) -> String;
|
|
|
|
fn transparent_colour(&self) -> Option<Colour>;
|
|
|
|
fn tilesize(&self) -> TileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct ConfigV1 {
|
|
|
|
version: String,
|
|
|
|
crate_prefix: Option<String>,
|
|
|
|
|
|
|
|
image: HashMap<String, ImageV1>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Config for ConfigV1 {
|
|
|
|
fn crate_prefix(&self) -> String {
|
2021-07-22 07:46:22 +10:00
|
|
|
self.crate_prefix
|
|
|
|
.clone()
|
|
|
|
.unwrap_or_else(|| "agb".to_owned())
|
2021-07-22 05:59:25 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
fn images(&self) -> HashMap<String, &dyn Image> {
|
2021-07-22 07:46:22 +10:00
|
|
|
self.image
|
|
|
|
.iter()
|
|
|
|
.map(|(filename, image)| (filename.clone(), image as &dyn Image))
|
|
|
|
.collect()
|
2021-07-22 05:59:25 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
pub struct ImageV1 {
|
|
|
|
filename: String,
|
|
|
|
transparent_colour: Option<String>,
|
|
|
|
tile_size: TileSizeV1,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Image for ImageV1 {
|
|
|
|
fn filename(&self) -> String {
|
|
|
|
self.filename.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn transparent_colour(&self) -> Option<Colour> {
|
|
|
|
if let Some(colour) = &self.transparent_colour {
|
|
|
|
if colour.len() != 6 {
|
|
|
|
panic!("Expected colour to be 6 characters, got {}", colour);
|
|
|
|
}
|
|
|
|
|
|
|
|
let r = u8::from_str_radix(&colour[0..2], 16).unwrap();
|
|
|
|
let g = u8::from_str_radix(&colour[2..4], 16).unwrap();
|
|
|
|
let b = u8::from_str_radix(&colour[4..6], 16).unwrap();
|
|
|
|
|
|
|
|
return Some(Colour::from_rgb(r, g, b));
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tilesize(&self) -> TileSize {
|
|
|
|
self.tile_size.into()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize, Clone, Copy)]
|
|
|
|
pub enum TileSizeV1 {
|
|
|
|
#[serde(rename = "8x8")]
|
|
|
|
Tile8,
|
2021-07-22 07:07:09 +10:00
|
|
|
#[serde(rename = "16x16")]
|
|
|
|
Tile16,
|
2021-10-31 04:22:09 +11:00
|
|
|
#[serde(rename = "32x32")]
|
|
|
|
Tile32,
|
2021-07-22 05:59:25 +10:00
|
|
|
}
|
|
|
|
|
2021-07-22 07:19:28 +10:00
|
|
|
impl From<TileSizeV1> for TileSize {
|
|
|
|
fn from(item: TileSizeV1) -> Self {
|
|
|
|
match item {
|
2021-07-22 05:59:25 +10:00
|
|
|
TileSizeV1::Tile8 => TileSize::Tile8,
|
2021-07-22 07:07:09 +10:00
|
|
|
TileSizeV1::Tile16 => TileSize::Tile16,
|
2021-10-31 04:22:09 +11:00
|
|
|
TileSizeV1::Tile32 => TileSize::Tile32,
|
2021-07-22 05:59:25 +10:00
|
|
|
}
|
|
|
|
}
|
2021-07-22 07:19:28 +10:00
|
|
|
}
|