use std::io;
use toml;
use GameResult;
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum FullscreenType {
Off,
True,
Desktop,
}
use sdl2::video::FullscreenType as SdlFullscreenType;
impl From<SdlFullscreenType> for FullscreenType {
fn from(other: SdlFullscreenType) -> Self {
match other {
SdlFullscreenType::Off => FullscreenType::Off,
SdlFullscreenType::True => FullscreenType::True,
SdlFullscreenType::Desktop => FullscreenType::Desktop,
}
}
}
impl From<FullscreenType> for SdlFullscreenType {
fn from(other: FullscreenType) -> Self {
match other {
FullscreenType::Off => SdlFullscreenType::Off,
FullscreenType::True => SdlFullscreenType::True,
FullscreenType::Desktop => SdlFullscreenType::Desktop,
}
}
}
#[derive(Debug, Copy, Clone, SmartDefault, Serialize, Deserialize, PartialEq, Eq)]
pub struct WindowMode {
#[default = r#"800"#]
pub width: u32,
#[default = r#"600"#]
pub height: u32,
#[default = r#"false"#]
pub borderless: bool,
#[default = r#"FullscreenType::Off"#]
pub fullscreen_type: FullscreenType,
#[default = r#"true"#]
pub vsync: bool,
#[default = r#"0"#]
pub min_width: u32,
#[default = r#"0"#]
pub min_height: u32,
#[default = r#"0"#]
pub max_width: u32,
#[default = r#"0"#]
pub max_height: u32,
}
impl WindowMode {
pub fn borderless(mut self, borderless: bool) -> Self {
self.borderless = borderless;
self
}
pub fn fullscreen_type(mut self, fullscreen_type: FullscreenType) -> Self {
self.fullscreen_type = fullscreen_type;
self
}
pub fn vsync(mut self, vsync: bool) -> Self {
self.vsync = vsync;
self
}
pub fn dimensions(mut self, width: u32, height: u32) -> Self {
self.width = width;
self.height = height;
self
}
pub fn min_dimensions(mut self, width: u32, height: u32) -> Self {
self.min_width = width;
self.min_height = height;
self
}
pub fn max_dimensions(mut self, width: u32, height: u32) -> Self {
self.max_width = width;
self.max_height = height;
self
}
}
#[derive(Debug, Clone, SmartDefault, Serialize, Deserialize, PartialEq, Eq)]
pub struct WindowSetup {
#[default = r#""An easy, good game".to_owned()"#]
pub title: String,
#[default = r#""".to_owned()"#]
pub icon: String,
#[default = r#"false"#]
pub resizable: bool,
#[default = r#"true"#]
pub allow_highdpi: bool,
#[default = r#"NumSamples::One"#]
pub samples: NumSamples,
}
impl WindowSetup {
pub fn title(mut self, title: &str) -> Self {
self.title = title.to_owned();
self
}
pub fn icon(mut self, icon: &str) -> Self {
self.icon = icon.to_owned();
self
}
pub fn resizable(mut self, resizable: bool) -> Self {
self.resizable = resizable;
self
}
pub fn allow_highdpi(mut self, allow: bool) -> Self {
self.allow_highdpi = allow;
self
}
pub fn samples(mut self, samples: u32) -> Option<Self> {
match NumSamples::from_u32(samples) {
Some(s) => {
self.samples = s;
Some(self)
}
None => None,
}
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq, SmartDefault)]
#[serde(tag = "type")]
pub enum Backend {
#[default]
OpenGL {
#[default = r#"3"#]
major: u8,
#[default = r#"2"#]
minor: u8,
},
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum NumSamples {
One = 1,
Two = 2,
Four = 4,
Eight = 8,
Sixteen = 16,
}
impl NumSamples {
pub fn from_u32(i: u32) -> Option<NumSamples> {
match i {
1 => Some(NumSamples::One),
2 => Some(NumSamples::Two),
4 => Some(NumSamples::Four),
8 => Some(NumSamples::Eight),
16 => Some(NumSamples::Sixteen),
_ => None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, SmartDefault)]
pub struct Conf {
pub window_mode: WindowMode,
pub window_setup: WindowSetup,
pub backend: Backend,
}
impl Conf {
pub fn new() -> Self {
Self::default()
}
pub fn from_toml_file<R: io::Read>(file: &mut R) -> GameResult<Conf> {
let mut s = String::new();
file.read_to_string(&mut s)?;
let decoded = toml::from_str(&s)?;
Ok(decoded)
}
pub fn to_toml_file<W: io::Write>(&self, file: &mut W) -> GameResult<()> {
let s = toml::to_vec(self)?;
file.write_all(&s)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use conf;
#[test]
fn encode_round_trip() {
let c1 = conf::Conf::new();
let mut writer = Vec::new();
let _c = c1.to_toml_file(&mut writer).unwrap();
let mut reader = writer.as_slice();
let c2 = conf::Conf::from_toml_file(&mut reader).unwrap();
assert_eq!(c1, c2);
}
}