From 97f2678563e6ca997ea33d7befe38ab2acfa01a9 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Sat, 14 Dec 2019 03:23:46 +0100 Subject: add preliminary support for user configurations --- src/useropts.rs | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/useropts.rs (limited to 'src/useropts.rs') diff --git a/src/useropts.rs b/src/useropts.rs new file mode 100644 index 0000000..e6de8de --- /dev/null +++ b/src/useropts.rs @@ -0,0 +1,127 @@ +//! Support for loading user defined rendering options. +//! +//! User options are given in a toml file, for example +//! +//! ```toml +//! skill_size = 20 +//! ``` +//! +//! The file is automatically deserialized by serde, so all fields defined in +//! [`UserOptions`](struct.UserOptions.html) can be used. +use image::Rgba; +use rusttype::Font; +use serde::{Deserialize, Serialize}; +use std::{error::Error, fmt, fs, io, path::Path}; + +use super::render::{Alignment, RenderOptions}; + +/// Error that can occur during loading or converting user options. +#[derive(Debug)] +pub enum ConfigError { + Io(io::Error), + Serialization(toml::de::Error), + Font(rusttype::Error), +} + +error_froms! { + ConfigError, + err: io::Error => ConfigError::Io(err), + err: toml::de::Error => ConfigError::Serialization(err), + err: rusttype::Error => ConfigError::Font(err), +} + +impl fmt::Display for ConfigError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "ConfigError: ")?; + match *self { + ConfigError::Io(_) => write!(f, "input/output error"), + ConfigError::Serialization(_) => write!(f, "serialization error"), + ConfigError::Font(_) => write!(f, "could not load the font"), + } + } +} + +impl Error for ConfigError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match *self { + ConfigError::Io(ref err) => Some(err), + ConfigError::Serialization(ref err) => Some(err), + ConfigError::Font(ref err) => Some(err), + } + } +} + +macro_rules! maybe_take_from { + (from: $from:expr, to: $to:ident, $($field:ident,)*) => { + $( + if let Some(data) = $from.$field { + $to.$field = data; + } + )* + } +} + +/// A struct for deserializing user defined options. +/// +/// This is basically a struct containing the same fields, but optional. If a field is given, it +/// should override the corresponding field in +/// [`RenderOptions`](../render/struct.RenderOptions.html). +/// +/// Some fields require some pre-processing, as the proper type cannot be serialized (e.g. +/// `image::Rgba` for `background_color`). +#[derive(Debug, Serialize, Deserialize)] +pub struct UserOptions { + pub traitline_x_offset: Option, + pub trait_size: Option, + pub line_color: Option<[u8; 4]>, + pub line_height: Option, + pub text_size: Option, + pub background_color: Option<[u8; 4]>, + pub font_path: Option, + pub render_specialization_names: Option, + pub skill_alignment: Option, +} + +impl UserOptions { + /// Converts this `UserOptions` to a proper + /// [`RenderOptions`](../render/struct.RenderOptions.html). + pub fn convert(self) -> Result { + let mut result = RenderOptions::default(); + + if let Some(data) = self.background_color { + result.background_color = Rgba(data); + } + + if let Some(data) = self.line_color { + result.line_color = Rgba(data); + } + + if let Some(path) = self.font_path { + let data = fs::read(path)?; + let font = Font::from_bytes(data)?; + result.font = font; + } + + maybe_take_from! { + from: self, to: result, + traitline_x_offset, + trait_size, + line_height, + text_size, + render_specialization_names, + skill_alignment, + } + + Ok(result) + } +} + +/// Load user given options from the given file path. +/// +/// This is basically a convenience function around reading the data, deserializing it from toml +/// and returning [`UserOptions::convert`](struct.UserOptions.html#method.convert). +pub fn load_file>(path: P) -> Result { + let data = fs::read(path)?; + let opts = toml::from_slice::(&data)?; + opts.convert() +} -- cgit v1.2.3 From 7f2f9b03debc7fc16f9614df7cb6fa4c0999d128 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Wed, 25 Dec 2019 00:56:44 +0100 Subject: add more user configurable options --- src/useropts.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/useropts.rs') diff --git a/src/useropts.rs b/src/useropts.rs index e6de8de..2e98926 100644 --- a/src/useropts.rs +++ b/src/useropts.rs @@ -71,14 +71,20 @@ macro_rules! maybe_take_from { /// `image::Rgba` for `background_color`). #[derive(Debug, Serialize, Deserialize)] pub struct UserOptions { + pub skill_size: Option, + pub traitline_brightness: Option, + pub traitline_use_gradient: Option, + pub traitline_gradient_size: Option, pub traitline_x_offset: Option, pub trait_size: Option, pub line_color: Option<[u8; 4]>, pub line_height: Option, + pub font_path: Option, + pub text_color: Option<[u8; 4]>, pub text_size: Option, pub background_color: Option<[u8; 4]>, - pub font_path: Option, pub render_specialization_names: Option, + pub skill_offset: Option, pub skill_alignment: Option, } @@ -96,6 +102,10 @@ impl UserOptions { result.line_color = Rgba(data); } + if let Some(data) = self.text_color { + result.text_color = Rgba(data); + } + if let Some(path) = self.font_path { let data = fs::read(path)?; let font = Font::from_bytes(data)?; @@ -104,11 +114,16 @@ impl UserOptions { maybe_take_from! { from: self, to: result, + skill_size, + traitline_brightness, + traitline_use_gradient, + traitline_gradient_size, traitline_x_offset, trait_size, line_height, text_size, render_specialization_names, + skill_offset, skill_alignment, } -- cgit v1.2.3