Update.
This commit is contained in:
parent
4d092d56a5
commit
a4dee7bd9b
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -978,6 +978,16 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "erased-serde"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"typeid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.10"
|
||||
@ -1644,6 +1654,15 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inventory"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5d80fade88dd420ce0d9ab6f7c58ef2272dde38db874657950f827d4982c817"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
@ -2516,6 +2535,8 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum_macros",
|
||||
"typetag",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3353,12 +3374,42 @@ version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||
|
||||
[[package]]
|
||||
name = "typeid"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e"
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "typetag"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "044fc3365ddd307c297fe0fe7b2e70588cdab4d0f62dc52055ca0d11b174cf0e"
|
||||
dependencies = [
|
||||
"erased-serde",
|
||||
"inventory",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"typetag-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typetag-impl"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9d30226ac9cbd2d1ff775f74e8febdab985dab14fb14aa2582c29a92d5555dc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.7"
|
||||
@ -3436,6 +3487,16 @@ version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
||||
@ -5,8 +5,10 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
config = "0.15.4"
|
||||
iced = "0.13.1"
|
||||
iced = { version = "0.13.1", features = ["debug"] }
|
||||
itertools = "0.13.0"
|
||||
serde = { version = "1.0.216", features = ["derive"] }
|
||||
serde_json = "1.0.134"
|
||||
strum_macros = "0.26.4"
|
||||
typetag = "0.2.19"
|
||||
uuid = { version = "1.11.0", features = ["v4", "serde"] }
|
||||
|
||||
@ -1,23 +1,38 @@
|
||||
use iced::widget::{container, text, Container, column};
|
||||
use iced::{
|
||||
widget::{button, column, container, horizontal_rule, row, text, toggler, vertical_rule},
|
||||
Element, Task,
|
||||
};
|
||||
|
||||
use crate::models::{FilterConfig, FilterText, Settings};
|
||||
use crate::models::{Filter, FilterConfig, FilterRule, FilterText, Settings};
|
||||
|
||||
use super::rule_list;
|
||||
|
||||
pub struct App {
|
||||
pub settings: Settings,
|
||||
pub filter_config: FilterConfig
|
||||
pub settings: Settings,
|
||||
pub filter_config: FilterConfig,
|
||||
}
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
RuleList(rule_list::Message),
|
||||
}
|
||||
impl App {
|
||||
pub fn view(&self) -> Container<Message> {
|
||||
container(column![
|
||||
text(format!("{:?}", &self.settings)),
|
||||
text(format!("{:?}", &self.filter_config.to_filter_text()))
|
||||
]).padding(8)
|
||||
}
|
||||
|
||||
pub fn update(&mut self, message: Message) {
|
||||
pub fn view(state: &App) -> Element<Message> {
|
||||
container(
|
||||
row![
|
||||
rule_list::view(&state.filter_config).map(Message::RuleList),
|
||||
vertical_rule(2),
|
||||
column![]
|
||||
]
|
||||
.spacing(8),
|
||||
)
|
||||
.padding(8)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn update(state: &mut App, msg: Message) -> Task<Message> {
|
||||
match msg {
|
||||
Message::RuleList(msg) => {
|
||||
rule_list::update(&mut state.filter_config, msg).map(Message::RuleList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
mod app;
|
||||
|
||||
pub use app::*;
|
||||
pub mod app;
|
||||
mod rule_detail;
|
||||
mod rule_item;
|
||||
mod rule_list;
|
||||
|
||||
0
src/components/rule_detail.rs
Normal file
0
src/components/rule_detail.rs
Normal file
49
src/components/rule_item.rs
Normal file
49
src/components/rule_item.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use iced::{
|
||||
widget::{button, row, text, toggler},
|
||||
Element, Task,
|
||||
};
|
||||
|
||||
use crate::models::{Filter, FilterRule, FilterText};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
TogglerToggled(bool),
|
||||
Delete,
|
||||
MoveUp,
|
||||
MoveDown,
|
||||
}
|
||||
|
||||
pub fn view(state: &Filter) -> Element<Message> {
|
||||
match &state.rule {
|
||||
FilterRule::Leaf(_) => row![
|
||||
button(text("x").size(10))
|
||||
.padding(4)
|
||||
.on_press(Message::Delete),
|
||||
button(text("↑").size(10))
|
||||
.padding(4)
|
||||
.on_press(Message::MoveUp),
|
||||
button(text("↓").size(10))
|
||||
.padding(4)
|
||||
.on_press(Message::MoveDown),
|
||||
toggler(state.enabled)
|
||||
.label("")
|
||||
.on_toggle(Message::TogglerToggled),
|
||||
text(format!("{}", state.to_filter_text().replace("\n", " ")))
|
||||
]
|
||||
.spacing(4),
|
||||
FilterRule::Group(group) => todo!(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn update(state: &mut Filter, msg: Message) -> Task<Message> {
|
||||
match msg {
|
||||
Message::TogglerToggled(toggled) => {
|
||||
state.enabled = toggled;
|
||||
Task::none()
|
||||
}
|
||||
Message::Delete => todo!(),
|
||||
Message::MoveUp => todo!(),
|
||||
Message::MoveDown => todo!(),
|
||||
}
|
||||
}
|
||||
64
src/components/rule_list.rs
Normal file
64
src/components/rule_list.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use iced::{
|
||||
widget::{button, column, keyed_column},
|
||||
Element, Task,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::{Filter, FilterConfig};
|
||||
|
||||
use super::rule_item;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
AddRule,
|
||||
RuleItem(Uuid, rule_item::Message),
|
||||
}
|
||||
|
||||
pub fn view(state: &FilterConfig) -> Element<Message> {
|
||||
let rows = keyed_column(state.filters.iter().map(|filter| {
|
||||
(
|
||||
filter.id,
|
||||
rule_item::view(filter).map(|msg| Message::RuleItem(filter.id, msg)),
|
||||
)
|
||||
}))
|
||||
.spacing(4);
|
||||
column![button("Add Rule").on_press(Message::AddRule), rows]
|
||||
.spacing(4)
|
||||
.into()
|
||||
}
|
||||
|
||||
pub fn update(state: &mut FilterConfig, msg: Message) -> Task<Message> {
|
||||
match msg {
|
||||
Message::AddRule => {
|
||||
state.filters.push(Filter::default_leaf());
|
||||
Task::none()
|
||||
}
|
||||
Message::RuleItem(uuid, rule_item::Message::Delete) => {
|
||||
state.filters.retain(|f| f.id != uuid);
|
||||
Task::none()
|
||||
}
|
||||
Message::RuleItem(uuid, rule_item::Message::MoveUp) => {
|
||||
if let Some(index) = state.filters.iter().position(|f| f.id == uuid) {
|
||||
if index > 0 {
|
||||
state.filters.swap(index, index - 1);
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::RuleItem(uuid, rule_item::Message::MoveDown) => {
|
||||
if let Some(index) = state.filters.iter().position(|f| f.id == uuid) {
|
||||
if index < state.filters.len() - 1 {
|
||||
state.filters.swap(index, index + 1);
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::RuleItem(uuid, msg) => {
|
||||
if let Some(filter) = state.filters.iter_mut().find(|filter| filter.id == uuid) {
|
||||
rule_item::update(filter, msg).map(move |msg| Message::RuleItem(uuid, msg))
|
||||
} else {
|
||||
Task::none()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/main.rs
55
src/main.rs
@ -1,21 +1,52 @@
|
||||
mod models;
|
||||
mod components;
|
||||
mod models;
|
||||
|
||||
use components::App;
|
||||
use iced::{Size, Task, Theme};
|
||||
use models::Settings;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use components::app::App;
|
||||
use config::Config;
|
||||
use iced::{Size, Task, Theme};
|
||||
use models::{Filter, FilterConfig, FilterLeaf, FilterRule, Level, Line, Settings};
|
||||
use uuid::Uuid;
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
let settings = Config::builder()
|
||||
.add_source(config::File::with_name("config/settings.json"))
|
||||
.build().unwrap().try_deserialize::<Settings>().unwrap();
|
||||
iced::application("POE2 Loot Filter Config Tools", App::update, App::view)
|
||||
.add_source(config::File::with_name("config/settings.json"))
|
||||
.build()
|
||||
.unwrap()
|
||||
.try_deserialize::<Settings>()
|
||||
.unwrap();
|
||||
let mut lines = HashMap::new();
|
||||
lines.insert(
|
||||
"k".to_string(),
|
||||
Line::AreaLevel(
|
||||
settings.op(&"<".to_string()).unwrap(),
|
||||
Level::new(80).unwrap(),
|
||||
),
|
||||
);
|
||||
let filter_config = FilterConfig {
|
||||
filters: vec![Filter {
|
||||
id: Uuid::new_v4(),
|
||||
enabled: true,
|
||||
rule: FilterRule::Leaf(FilterLeaf { show: true, lines }),
|
||||
}],
|
||||
};
|
||||
|
||||
iced::application(
|
||||
"POE2 Loot Filter Config",
|
||||
components::app::update,
|
||||
components::app::view,
|
||||
)
|
||||
.theme(|_| Theme::GruvboxDark)
|
||||
.window_size(Size::new(1920.0 / 2., 1080.0 / 2.))
|
||||
.centered()
|
||||
.run_with(|| (App {
|
||||
settings: settings,
|
||||
filter_config: vec![]
|
||||
}, Task::none()))
|
||||
}
|
||||
.run_with(move || {
|
||||
(
|
||||
App {
|
||||
settings,
|
||||
filter_config,
|
||||
},
|
||||
Task::none(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct RangedNumber<const MIN: u32, const MAX: u32>(u32);
|
||||
|
||||
impl<const MIN: u32, const MAX: u32> RangedNumber<MIN, MAX> {
|
||||
|
||||
@ -1,51 +1,122 @@
|
||||
use super::{Color, Filter, FilterConfig, Line};
|
||||
use itertools::Itertools;
|
||||
|
||||
use super::{Color, Filter, FilterConfig, FilterLeaf, FilterRule, Line};
|
||||
|
||||
pub trait FilterText {
|
||||
fn to_filter_text(&self) -> String;
|
||||
fn to_filter_text(&self) -> String;
|
||||
}
|
||||
|
||||
impl FilterText for FilterConfig {
|
||||
fn to_filter_text(&self) -> String {
|
||||
self.filters.iter().rev()
|
||||
.map(|filter| {filter.to_filter_text()})
|
||||
.collect::<Vec<_>>().join("\n\n")
|
||||
}
|
||||
impl<'a> FilterText for FilterConfig {
|
||||
fn to_filter_text(&self) -> String {
|
||||
self.filters
|
||||
.iter()
|
||||
.rev()
|
||||
.filter(|filter| filter.enabled)
|
||||
.map(|filter| filter.to_filter_text())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterRule {
|
||||
fn ungroup(&self) -> Vec<FilterLeaf> {
|
||||
match self {
|
||||
FilterRule::Leaf(leaf) => vec![leaf.clone()],
|
||||
FilterRule::Group(group) => group
|
||||
.filters
|
||||
.iter()
|
||||
.filter(|filter| filter.enabled)
|
||||
.flat_map(|filter| filter.rule.ungroup())
|
||||
.map(|leaf| {
|
||||
let mut new_leaf = leaf.clone();
|
||||
for (key, value) in &group.lines {
|
||||
new_leaf.lines.insert(key.to_string(), value.clone());
|
||||
}
|
||||
new_leaf
|
||||
})
|
||||
.collect_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for FilterRule {
|
||||
fn to_filter_text(&self) -> String {
|
||||
self.ungroup()
|
||||
.iter()
|
||||
.map(|leaf| {
|
||||
if leaf.show { "Show" } else { "Hide" }.to_string()
|
||||
+ "\n"
|
||||
+ &leaf
|
||||
.lines
|
||||
.values()
|
||||
.map(|line| line.to_filter_text())
|
||||
.join("\n")
|
||||
})
|
||||
.join("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Filter {
|
||||
fn to_filter_text(&self) -> String {
|
||||
let head = if self.show {"Show"} else {"Hide"};
|
||||
head.to_owned() + "\n" + &self.lines.iter().map(|line| {line.to_filter_text()})
|
||||
.collect::<Vec<_>>().join("\n")
|
||||
}
|
||||
fn to_filter_text(&self) -> String {
|
||||
self.rule.to_filter_text()
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Line {
|
||||
fn to_filter_text(&self) -> String {
|
||||
match self {
|
||||
Line::Class(item_class) => format!("Class {}", item_class.iter().map(|item| format!(r#""{}""#, item.value())).collect::<Vec<_>>().join(" ")),
|
||||
Line::BaseType(item_base_type) => format!("BaseType {}", item_base_type.iter().map(|item| format!(r#""{}""#, item.value())).collect::<Vec<_>>().join(" ")),
|
||||
Line::AreaLevel(op, level) => format!("AreaLevel {} {}", op.value(), level.value()),
|
||||
Line::DropLevel(op, level) => format!("DropLevel {} {}", op.value(), level.value()),
|
||||
Line::ItemLevel(op, level) => format!("ItemLevel {} {}", op.value(), level.value()),
|
||||
Line::Rarity(op, item_rarity) => format!("Rarity {} {}", op.value(), item_rarity.value()),
|
||||
Line::Sockets(op, i) => format!("Sockets {} {}", op.value(), i),
|
||||
Line::Quality(op, i) => format!("Quality {} {}", op.value(), i),
|
||||
Line::StackSize(op, i) => format!("StackSize {} {}", op.value(), i),
|
||||
Line::WaystoneTier(op, waystone_tier) => format!("WaystoneTier {} {}", op.value(), waystone_tier.value()),
|
||||
Line::SetFontSize(font_size) => format!("SetFontSize {}", font_size.value()),
|
||||
Line::SetTextColor(color) => format!("SetTextColor {}", color.to_filter_text()),
|
||||
Line::SetBorderColor(color) => format!("SetBorderColor {}", color.to_filter_text()),
|
||||
Line::SetBackgroundColor(color) => format!("SetBackgroundColor {}", color.to_filter_text()),
|
||||
Line::PlayAlertSound(alert_sound_id, alert_sound_volume) => format!("PlayAlertSound {} {}", alert_sound_id.value(), alert_sound_volume.value()),
|
||||
Line::PlayEffect(game_color) => format!("PlayEffect {}", game_color.value()),
|
||||
Line::MinimapIcon(minimap_icon_size, game_color, minimap_icon_shape) => format!("MinimapIcon {} {} {}", minimap_icon_size.value(), game_color.value(), minimap_icon_shape.value()),
|
||||
}
|
||||
}
|
||||
fn to_filter_text(&self) -> String {
|
||||
match self {
|
||||
Line::Class(item_class) => format!(
|
||||
"Class {}",
|
||||
item_class
|
||||
.iter()
|
||||
.map(|item| format!(r#""{}""#, item.value()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
),
|
||||
Line::BaseType(item_base_type) => format!(
|
||||
"BaseType {}",
|
||||
item_base_type
|
||||
.iter()
|
||||
.map(|item| format!(r#""{}""#, item.value()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
),
|
||||
Line::AreaLevel(op, level) => format!("AreaLevel {} {}", op.value(), level.value()),
|
||||
Line::DropLevel(op, level) => format!("DropLevel {} {}", op.value(), level.value()),
|
||||
Line::ItemLevel(op, level) => format!("ItemLevel {} {}", op.value(), level.value()),
|
||||
Line::Rarity(op, item_rarity) => {
|
||||
format!("Rarity {} {}", op.value(), item_rarity.value())
|
||||
}
|
||||
Line::Sockets(op, i) => format!("Sockets {} {}", op.value(), i),
|
||||
Line::Quality(op, i) => format!("Quality {} {}", op.value(), i),
|
||||
Line::StackSize(op, i) => format!("StackSize {} {}", op.value(), i),
|
||||
Line::WaystoneTier(op, waystone_tier) => {
|
||||
format!("WaystoneTier {} {}", op.value(), waystone_tier.value())
|
||||
}
|
||||
Line::SetFontSize(font_size) => format!("SetFontSize {}", font_size.value()),
|
||||
Line::SetTextColor(color) => format!("SetTextColor {}", color.to_filter_text()),
|
||||
Line::SetBorderColor(color) => format!("SetBorderColor {}", color.to_filter_text()),
|
||||
Line::SetBackgroundColor(color) => {
|
||||
format!("SetBackgroundColor {}", color.to_filter_text())
|
||||
}
|
||||
Line::PlayAlertSound(alert_sound_id, alert_sound_volume) => format!(
|
||||
"PlayAlertSound {} {}",
|
||||
alert_sound_id.value(),
|
||||
alert_sound_volume.value()
|
||||
),
|
||||
Line::PlayEffect(game_color) => format!("PlayEffect {}", game_color.value()),
|
||||
Line::MinimapIcon(minimap_icon_size, game_color, minimap_icon_shape) => format!(
|
||||
"MinimapIcon {} {} {}",
|
||||
minimap_icon_size.value(),
|
||||
game_color.value(),
|
||||
minimap_icon_shape.value()
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FilterText for Color {
|
||||
fn to_filter_text(&self) -> String {
|
||||
format!("{} {} {} {}", self.r, self.g, self.b, self.a)
|
||||
}
|
||||
}
|
||||
fn to_filter_text(&self) -> String {
|
||||
format!("{} {} {} {}", self.r, self.g, self.b, self.a)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,27 +1,60 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::base::RangedNumber;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct FilterConfig {
|
||||
pub filters: Vec<Filter>,
|
||||
test: dyn Test
|
||||
}
|
||||
|
||||
trait Test: std::fmt::Debug {}
|
||||
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Filter {
|
||||
pub show: bool,
|
||||
pub lines: Vec<Line>,
|
||||
pub id: uuid::Uuid,
|
||||
pub enabled: bool,
|
||||
pub rule: FilterRule,
|
||||
}
|
||||
|
||||
impl Filter {
|
||||
pub fn default_leaf() -> Self {
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
enabled: true,
|
||||
rule: FilterRule::Leaf(FilterLeaf::default()),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
fn default_group() -> Self {
|
||||
Self {
|
||||
id: Uuid::new_v4(),
|
||||
enabled: true,
|
||||
rule: FilterRule::Group(FilterGroup::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub enum FilterRule {
|
||||
Leaf(FilterLeaf),
|
||||
Group(FilterGroup),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct FilterLeaf {
|
||||
pub show: bool,
|
||||
pub lines: HashMap<String, Line>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
pub struct FilterGroup {
|
||||
pub lines: HashMap<String, Line>,
|
||||
pub filters: Vec<Filter>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Color {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
@ -31,7 +64,7 @@ pub struct Color {
|
||||
|
||||
pub type Level = RangedNumber<1, 100>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub enum Line {
|
||||
Class(Vec<ItemClass>),
|
||||
BaseType(Vec<ItemBaseType>),
|
||||
@ -68,45 +101,54 @@ pub struct Settings {
|
||||
|
||||
impl Settings {
|
||||
fn format_err(value: &str, category: &str, options: &Vec<String>) -> String {
|
||||
format!("{} is not a valid {}, options are: {}", value, category, options.iter().join(" "))
|
||||
format!(
|
||||
"{} is not a valid {}, options are: {}",
|
||||
value,
|
||||
category,
|
||||
options.iter().join(" ")
|
||||
)
|
||||
}
|
||||
pub fn base_type(&self, s: &String) -> Result<ItemBaseType, String> {
|
||||
if self.base_types.contains(s) {
|
||||
if !self.base_types.contains(s) {
|
||||
Err(Self::format_err(s, "BaseType", &self.base_types))
|
||||
} else {
|
||||
Ok(ItemBaseType(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn class(&self, s: &String) -> Result<ItemClass, String> {
|
||||
if self.classes.contains(s) {
|
||||
if !self.classes.contains(s) {
|
||||
Err(Self::format_err(s, "Class", &self.classes))
|
||||
} else {
|
||||
Ok(ItemClass(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn rarity(&self, s: &String) -> Result<ItemRarity, String> {
|
||||
if self.rarities.contains(s) {
|
||||
if !self.rarities.contains(s) {
|
||||
Err(Self::format_err(s, "Rarity", &self.rarities))
|
||||
} else {
|
||||
Ok(ItemRarity(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn op(&self, s: &String) -> Result<Op, String> {
|
||||
if self.ops.contains(s) {
|
||||
if !self.ops.contains(s) {
|
||||
Err(Self::format_err(s, "Operator", &self.ops))
|
||||
} else {
|
||||
Ok(Op(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn minimap_icon_shape(&self, s: &String) -> Result<MinimapIconShape, String> {
|
||||
if self.minimap_icon_shapes.contains(s) {
|
||||
Err(Self::format_err(s, "MinimapIconShape", &self.minimap_icon_shapes))
|
||||
if !self.minimap_icon_shapes.contains(s) {
|
||||
Err(Self::format_err(
|
||||
s,
|
||||
"MinimapIconShape",
|
||||
&self.minimap_icon_shapes,
|
||||
))
|
||||
} else {
|
||||
Ok(MinimapIconShape(s.to_string()))
|
||||
}
|
||||
}
|
||||
pub fn game_color(&self, s: &String) -> Result<GameColor, String> {
|
||||
if self.game_colors.contains(s) {
|
||||
if !self.game_colors.contains(s) {
|
||||
Err(Self::format_err(s, "GameColor", &self.game_colors))
|
||||
} else {
|
||||
Ok(GameColor(s.to_string()))
|
||||
@ -114,39 +156,51 @@ impl Settings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ItemBaseType(String);
|
||||
impl ItemBaseType {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct ItemClass(String);
|
||||
impl ItemClass {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct ItemRarity(String);
|
||||
impl ItemRarity {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct MinimapIconShape(String);
|
||||
impl MinimapIconShape {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct GameColor(String);
|
||||
impl GameColor {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct Op(String);
|
||||
|
||||
impl Op {
|
||||
pub fn value(&self) -> &str {&self.0}
|
||||
pub fn value(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user