use std::{
collections::{HashMap, HashSet},
fmt::{self, Display, Formatter},
ops::{Deref, RangeInclusive},
time::Duration,
};
pub use settings_schema_derive::SettingsSchema;
pub use serde::{Deserialize, Serialize};
pub use serde_json::to_value as to_json_value;
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub struct Percentage(f32);
impl Percentage {
pub fn new(value: u8) -> Self {
Self(value as f32 / 100.0)
}
pub fn new_normalized(value: f32) -> Self {
Self(value)
}
}
impl From<u8> for Percentage {
fn from(value: u8) -> Self {
Self(value as f32)
}
}
impl From<f32> for Percentage {
fn from(value: f32) -> Self {
Self(value)
}
}
impl Deref for Percentage {
type Target = f32;
fn deref(&self) -> &f32 {
&self.0
}
}
impl Display for Percentage {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}%", (self.0 * 100.0) as u8)
}
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub enum Switch<T> {
Enabled(T),
Disabled,
}
impl<T> Switch<T> {
pub fn as_option(&self) -> Option<&T> {
match self {
Self::Enabled(t) => Some(t),
Self::Disabled => None,
}
}
pub fn into_option(self) -> Option<T> {
match self {
Self::Enabled(t) => Some(t),
Self::Disabled => None,
}
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct OptionalDefault<C> {
pub set: bool,
pub content: C,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SwitchDefault<C> {
pub enabled: bool,
pub content: C,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct VectorDefault<T> {
pub element: T,
pub content: Vec<T>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct DictionaryDefault<T> {
pub key: String,
pub value: T,
pub content: Vec<(String, T)>,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum NumericGuiType {
Slider {
range: RangeInclusive<f64>,
step: Option<f64>,
logarithmic: bool,
},
TextBox,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub enum NumberType {
UnsignedInteger,
SignedInteger,
Float,
}
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
pub enum ChoiceControlType {
Dropdown,
ButtonGroup,
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct SchemaEntry<T> {
pub name: String,
pub strings: HashMap<String, String>,
pub flags: HashSet<String>,
pub content: T,
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum SchemaNode {
Section(Vec<SchemaEntry<SchemaNode>>),
Choice {
default: String,
variants: Vec<SchemaEntry<Option<SchemaNode>>>,
gui: Option<ChoiceControlType>,
},
Optional {
default_set: bool,
content: Box<SchemaNode>,
},
Switch {
default_enabled: bool,
content: Box<SchemaNode>,
},
Boolean {
default: bool,
},
Number {
default: f64,
ty: NumberType,
gui: NumericGuiType,
suffix: Option<String>,
},
Range {
default: [f64; 2],
ty: NumberType,
gui: NumericGuiType,
suffix: Option<String>,
},
Percentage {
default_normalized: f32,
range_normalized: Option<RangeInclusive<f32>>,
},
Duration {
default: Duration,
range: RangeInclusive<Duration>,
logarithmic: bool,
},
Text {
default: String,
},
Array(Vec<SchemaNode>),
Vector {
default_element: Box<SchemaNode>,
default: serde_json::Value,
},
Dictionary {
default_key: String,
default_value: Box<SchemaNode>,
default: serde_json::Value,
},
}