use serde::{Deserialize, Serialize};
pub trait EnumValue<'de>: glib::value::ToValue + Deserialize<'de> + Copy + Sized {
fn name(&self) -> String {
let value = self.to_value();
let (_, v) = glib::EnumValue::from_value(&value).unwrap();
v.nick().to_string()
}
fn toml_deserialize(item: Option<&toml_edit::Item>) -> Option<Self> {
use serde::de::IntoDeserializer;
item.cloned()?
.into_value()
.ok()
.map(toml_edit::Value::into_deserializer)
.and_then(|p| <Self as Deserialize>::deserialize(p).ok())
}
fn kebab_str_deserialize(s: &str) -> Option<Self> {
use serde::de::IntoDeserializer;
<Self as Deserialize>::deserialize(toml_edit::Value::into_deserializer(
toml_edit::value(s).into_value().ok()?,
))
.ok()
}
fn kebab_case_variants() -> &'static [&'static str];
}
#[derive(Debug, Deserialize, Serialize, Default, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "MarkColor")]
#[serde(rename_all = "kebab-case")]
pub enum MarkColor {
None,
Background,
#[default]
Icon,
}
impl EnumValue<'_> for MarkColor {
fn kebab_case_variants() -> &'static [&'static str] {
&["none", "background", "icon"]
}
}
#[derive(Debug, Deserialize, Serialize, Default, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "ShowMinimap")]
#[serde(rename_all = "kebab-case")]
pub enum ShowMinimap {
Never,
Always,
#[default]
WhenManipulating,
}
impl EnumValue<'_> for ShowMinimap {
fn kebab_case_variants() -> &'static [&'static str] {
&["never", "always", "when-manipulating"]
}
}
#[derive(Debug, Deserialize, Serialize, Default, Copy, Clone, PartialEq, Eq, glib::Enum)]
#[enum_type(name = "Theme")]
#[serde(rename_all = "kebab-case")]
pub enum Theme {
#[default]
SystemDefault,
Paperwhite,
}
impl EnumValue<'_> for Theme {
fn kebab_case_variants() -> &'static [&'static str] {
&["system-default", "paperwhite"]
}
}
impl Theme {
pub const PAPERWHITE_CSS: &[u8] = include_bytes!("../../themes/paperwhite/gtk.css");
}
#[test]
fn test_parse_toml() {
use crate::prelude::Color;
use toml_edit::Document;
const TOML: &str = r##"handle-size = 4.8500000000000005
line-width = 1.0
warp-cursor = false
guideline-width = 0.7999999999999998
mark-color = "none"
[canvas]
color = "#E6E6E4"
"##;
let doc = TOML.parse::<Document>().unwrap();
assert_eq!(doc["line-width"].as_float().unwrap(), 1.0);
assert!(!doc["warp-cursor"].as_bool().unwrap());
assert_eq!(
<MarkColor as EnumValue>::toml_deserialize(Some(&doc["mark-color"])).unwrap(),
MarkColor::None
);
assert_eq!(
Color::from_hex(doc["canvas"]["color"].as_str().unwrap()),
Color::from_hex("#E6E6E4")
);
let doc = r#"theme = "system-default"
other-theme = "paperwhite"
"#
.parse::<Document>()
.unwrap();
assert_eq!(
<Theme as EnumValue>::toml_deserialize(Some(&doc["theme"])).unwrap(),
Theme::SystemDefault
);
assert_eq!(
<Theme as EnumValue>::toml_deserialize(Some(&doc["other-theme"])).unwrap(),
Theme::Paperwhite
);
}