pub struct SchemaSection {
pub id: &'static str,
pub display_name: &'static str,
pub description: Option<&'static str>,
pub icon: Option<&'static str>,
pub order: i32,
pub prefs: &'static [Pref],
}
pub struct Pref {
pub key: &'static str,
pub display_name: &'static str,
pub description: Option<&'static str>,
pub kind: PrefKind,
pub widget: WidgetHint,
}
pub enum PrefKind {
Bool,
Int {
min: i64,
max: i64,
},
Float {
min: f64,
max: f64,
},
Str,
Enum {
options: &'static [(&'static str, &'static str)],
},
}
pub enum WidgetHint {
Auto,
NumberInput,
Hotkey,
Color,
Hidden,
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SectionInfo {
pub id: &'static str,
pub display_name: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<&'static str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub icon: Option<&'static str>,
pub order: i32,
pub prefs: Vec<PrefInfo>,
}
#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PrefInfo {
pub key: &'static str,
pub display_name: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<&'static str>,
pub kind: &'static str,
#[serde(skip_serializing_if = "Option::is_none")]
pub min: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<serde_json::Value>,
pub widget: &'static str,
}
impl SectionInfo {
pub fn from_section(section: &SchemaSection) -> Self {
SectionInfo {
id: section.id,
display_name: section.display_name,
description: section.description,
icon: section.icon,
order: section.order,
prefs: section.prefs.iter().map(PrefInfo::from_pref).collect(),
}
}
}
impl PrefInfo {
pub fn from_pref(pref: &Pref) -> Self {
let (kind, min, max, options) = match &pref.kind {
PrefKind::Bool => ("bool", None, None, None),
PrefKind::Int { min, max } => ("int", Some(*min as f64), Some(*max as f64), None),
PrefKind::Float { min, max } => ("float", Some(*min), Some(*max), None),
PrefKind::Str => ("str", None, None, None),
PrefKind::Enum { options } => ("enum", None, None, Some(serde_json::json!(options))),
};
PrefInfo {
key: pref.key,
display_name: pref.display_name,
description: pref.description,
kind,
min,
max,
options,
widget: widget_hint_str(&pref.widget),
}
}
}
fn widget_hint_str(hint: &WidgetHint) -> &'static str {
match hint {
WidgetHint::Auto => "auto",
WidgetHint::NumberInput => "numberInput",
WidgetHint::Hotkey => "hotkey",
WidgetHint::Color => "color",
WidgetHint::Hidden => "hidden",
}
}