From 1a8da781115d9d5d8c9a6d64b95a27b2fe1b1919 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sat, 7 Oct 2023 11:54:24 +0100 Subject: [PATCH 1/9] Extracted Attributes newtype. --- pubsubman/src/ui/publish_view.rs | 99 ++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 30 deletions(-) diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index ae29d14..7f70c09 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use pubsubman_backend::{ message::FrontendMessage, @@ -11,7 +11,7 @@ use crate::actions::publish_message; #[derive(Default)] pub struct PublishView { data: String, - attributes: Vec<(String, String)>, + attributes: Attributes, } impl PublishView { @@ -39,42 +39,16 @@ impl PublishView { .id_source(format!("{}-attributes", selected_topic.0)) .default_open(false) .show(ui, |ui| { - let mut attr_idx_to_delete = None; - if !self.attributes.is_empty() { egui::Grid::new(format!("{}-attributes-form", selected_topic.0)) .min_col_width(100.0) .num_columns(3) .spacing((0.0, 4.0)) .show(ui, |ui| { - for (idx, (id, val)) in self.attributes.iter_mut().enumerate() { - ui.add( - egui::TextEdit::singleline(id) - .desired_width(100.0) - .code_editor() - .hint_text("Key"), - ); - - ui.add( - egui::TextEdit::singleline(val) - .desired_width(100.0) - .code_editor() - .hint_text("Value"), - ); - - if ui.button("🗑").clicked() { - attr_idx_to_delete = Some(idx); - } - - ui.end_row(); - } + self.attributes.show(ui); }); } - if let Some(i) = attr_idx_to_delete { - self.attributes.remove(i); - } - if !self.attributes.is_empty() { ui.add_space(4.0); } @@ -94,6 +68,71 @@ impl PublishView { impl From<&mut PublishView> for PubsubMessageToPublish { fn from(val: &mut PublishView) -> Self { - Self::new(val.data.clone(), HashMap::from_iter(val.attributes.clone())) + Self::new( + val.data.clone(), + HashMap::from_iter(val.attributes.0.clone()), + ) + } +} + +#[derive(Default)] +struct Attributes(Vec<(String, String)>); + +impl Attributes { + fn key_indices_map(&self) -> HashMap> { + let mut index_map = HashMap::new(); + + for (index, (value, _)) in self.0.iter().enumerate() { + index_map + .entry(value.clone()) + .or_insert_with(HashSet::new) + .insert(index); + } + + index_map + } + + fn is_empty(&self) -> bool { + self.0.is_empty() + } + + fn push(&mut self, attr: (String, String)) { + self.0.push(attr); + } + + fn is_valid(&self) -> bool { + self.key_indices_map() + .values() + .all(|indices| indices.len() < 2) + } + + fn show(&mut self, ui: &mut egui::Ui) { + let mut attr_idx_to_delete = None; + + for (idx, (id, val)) in self.0.iter_mut().enumerate() { + ui.add( + egui::TextEdit::singleline(id) + .desired_width(100.0) + .code_editor() + .hint_text("Key"), + ); + + ui.add( + egui::TextEdit::singleline(val) + .desired_width(100.0) + .code_editor() + .hint_text("Value"), + ); + + if ui.button("🗑").clicked() { + attr_idx_to_delete = Some(idx); + } + + ui.end_row(); + } + + if let Some(i) = attr_idx_to_delete { + self.0.remove(i); + } } } From 5f102cc884f0dcc2c3d763c18af04a53fecaf3f5 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sat, 7 Oct 2023 13:39:18 +0100 Subject: [PATCH 2/9] Showing error frame around duplicate attribute keys. --- pubsubman/src/ui/publish_view.rs | 58 +++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index 7f70c09..3d0a650 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -35,7 +35,14 @@ impl PublishView { ); }); - egui::CollapsingHeader::new("Attributes") + let mut header_text = egui::RichText::new("Attributes"); + let attributes_valid = self.attributes.is_valid(); + + if !attributes_valid { + header_text = header_text.color(ui.visuals().error_fg_color); + }; + + egui::CollapsingHeader::new(header_text) .id_source(format!("{}-attributes", selected_topic.0)) .default_open(false) .show(ui, |ui| { @@ -60,7 +67,10 @@ impl PublishView { ui.add_space(8.0); - if ui.button("Publish").clicked() { + if ui + .add_enabled(attributes_valid, egui::Button::new("Publish")) + .clicked() + { publish_message(front_tx, selected_topic, self.into()) } } @@ -107,15 +117,22 @@ impl Attributes { } fn show(&mut self, ui: &mut egui::Ui) { + let key_indices_map = self.key_indices_map(); let mut attr_idx_to_delete = None; for (idx, (id, val)) in self.0.iter_mut().enumerate() { - ui.add( - egui::TextEdit::singleline(id) - .desired_width(100.0) - .code_editor() - .hint_text("Key"), - ); + let is_valid = key_indices_map + .get(id) + .is_some_and(|indices| indices.len() < 2); + + ui.validity_frame(is_valid).show(ui, |ui| { + ui.add( + egui::TextEdit::singleline(id) + .desired_width(100.0) + .code_editor() + .hint_text("Key"), + ); + }); ui.add( egui::TextEdit::singleline(val) @@ -136,3 +153,28 @@ impl Attributes { } } } + +trait ValidityFrame { + fn validity_frame(&self, is_valid: bool) -> egui::Frame; +} + +impl ValidityFrame for &mut egui::Ui { + fn validity_frame(&self, is_valid: bool) -> egui::Frame { + let (stroke, rounding) = if is_valid { + (egui::Stroke::NONE, egui::Rounding::ZERO) + } else { + ( + egui::Stroke { + width: 1.0, + color: self.visuals().error_fg_color, + }, + self.visuals().widgets.hovered.rounding, + ) + }; + + egui::Frame::none() + .stroke(stroke) + .inner_margin(2.0) + .rounding(rounding) + } +} From daaba523091ea5de1025a85289a63765ce844c5f Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 17:26:53 +0100 Subject: [PATCH 3/9] Passing in is_key_valid closure, and calculating attributes_valid from reused map. --- pubsubman/src/ui/publish_view.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index 3d0a650..c313a49 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -36,7 +36,8 @@ impl PublishView { }); let mut header_text = egui::RichText::new("Attributes"); - let attributes_valid = self.attributes.is_valid(); + let key_indices_map = self.attributes.key_indices_map(); + let attributes_valid = key_indices_map.iter().all(|(_, indices)| indices.len() < 2); if !attributes_valid { header_text = header_text.color(ui.visuals().error_fg_color); @@ -52,7 +53,11 @@ impl PublishView { .num_columns(3) .spacing((0.0, 4.0)) .show(ui, |ui| { - self.attributes.show(ui); + self.attributes.show(ui, |key| { + key_indices_map + .get(key) + .is_some_and(|indices| indices.len() < 2) + }); }); } @@ -110,24 +115,15 @@ impl Attributes { self.0.push(attr); } - fn is_valid(&self) -> bool { - self.key_indices_map() - .values() - .all(|indices| indices.len() < 2) - } - - fn show(&mut self, ui: &mut egui::Ui) { - let key_indices_map = self.key_indices_map(); + fn show(&mut self, ui: &mut egui::Ui, is_key_valid: impl Fn(&str) -> bool) { let mut attr_idx_to_delete = None; - for (idx, (id, val)) in self.0.iter_mut().enumerate() { - let is_valid = key_indices_map - .get(id) - .is_some_and(|indices| indices.len() < 2); + for (idx, (key, val)) in self.0.iter_mut().enumerate() { + let is_valid = is_key_valid(key); ui.validity_frame(is_valid).show(ui, |ui| { ui.add( - egui::TextEdit::singleline(id) + egui::TextEdit::singleline(key) .desired_width(100.0) .code_editor() .hint_text("Key"), From 28e24c67dcaaea9aea71833b97d0ba23ba094b74 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 17:31:54 +0100 Subject: [PATCH 4/9] Storing counts as values instead of indices. --- pubsubman/src/ui/publish_view.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index c313a49..2f4dcca 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use pubsubman_backend::{ message::FrontendMessage, @@ -36,10 +36,10 @@ impl PublishView { }); let mut header_text = egui::RichText::new("Attributes"); - let key_indices_map = self.attributes.key_indices_map(); - let attributes_valid = key_indices_map.iter().all(|(_, indices)| indices.len() < 2); + let attributes_key_count_map = self.attributes.key_count_map(); + let all_attributes_valid = attributes_key_count_map.iter().all(|(_, count)| *count < 2); - if !attributes_valid { + if !all_attributes_valid { header_text = header_text.color(ui.visuals().error_fg_color); }; @@ -54,9 +54,9 @@ impl PublishView { .spacing((0.0, 4.0)) .show(ui, |ui| { self.attributes.show(ui, |key| { - key_indices_map + attributes_key_count_map .get(key) - .is_some_and(|indices| indices.len() < 2) + .is_some_and(|count| *count < 2) }); }); } @@ -73,7 +73,7 @@ impl PublishView { ui.add_space(8.0); if ui - .add_enabled(attributes_valid, egui::Button::new("Publish")) + .add_enabled(all_attributes_valid, egui::Button::new("Publish")) .clicked() { publish_message(front_tx, selected_topic, self.into()) @@ -94,17 +94,14 @@ impl From<&mut PublishView> for PubsubMessageToPublish { struct Attributes(Vec<(String, String)>); impl Attributes { - fn key_indices_map(&self) -> HashMap> { - let mut index_map = HashMap::new(); - - for (index, (value, _)) in self.0.iter().enumerate() { - index_map - .entry(value.clone()) - .or_insert_with(HashSet::new) - .insert(index); + fn key_count_map(&self) -> HashMap { + let mut key_count_map = HashMap::new(); + + for (key, _) in self.0.iter() { + *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; } - index_map + key_count_map } fn is_empty(&self) -> bool { From 98489c64d5eb35894194cd450dc6aa03b3d1e1ab Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 17:55:08 +0100 Subject: [PATCH 5/9] Add caching for attributes key count map. --- pubsubman/src/ui/publish_view.rs | 46 +++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index 2f4dcca..c999fc2 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -36,7 +36,7 @@ impl PublishView { }); let mut header_text = egui::RichText::new("Attributes"); - let attributes_key_count_map = self.attributes.key_count_map(); + let attributes_key_count_map = key_count_map(ui.ctx(), &self.attributes); let all_attributes_valid = attributes_key_count_map.iter().all(|(_, count)| *count < 2); if !all_attributes_valid { @@ -90,20 +90,10 @@ impl From<&mut PublishView> for PubsubMessageToPublish { } } -#[derive(Default)] +#[derive(Default, Hash)] struct Attributes(Vec<(String, String)>); impl Attributes { - fn key_count_map(&self) -> HashMap { - let mut key_count_map = HashMap::new(); - - for (key, _) in self.0.iter() { - *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; - } - - key_count_map - } - fn is_empty(&self) -> bool { self.0.is_empty() } @@ -147,6 +137,38 @@ impl Attributes { } } +#[derive(Default)] +struct AttributesKeyCounter; + +impl AttributesKeyCounter { + fn key_count_map(&self, attributes: &Attributes) -> HashMap { + let mut key_count_map = HashMap::new(); + + for (key, _) in attributes.0.iter() { + *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; + } + + key_count_map + } +} + +fn key_count_map(ctx: &egui::Context, attributes: &Attributes) -> HashMap { + impl egui::util::cache::ComputerMut<&Attributes, HashMap> for AttributesKeyCounter { + fn compute(&mut self, attributes: &Attributes) -> HashMap { + self.key_count_map(attributes) + } + } + + type AttributesKeyCounterCache = + egui::util::cache::FrameCache, AttributesKeyCounter>; + + ctx.memory_mut(|mem| { + mem.caches + .cache::() + .get(attributes) + }) +} + trait ValidityFrame { fn validity_frame(&self, is_valid: bool) -> egui::Frame; } From 95eec88806add9aa251742ea182afcfc64ea4473 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 17:58:22 +0100 Subject: [PATCH 6/9] Extracted validity_frame module. --- pubsubman/src/ui/mod.rs | 1 + pubsubman/src/ui/publish_view.rs | 27 ++------------------------- pubsubman/src/ui/validity_frame.rs | 24 ++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 25 deletions(-) create mode 100644 pubsubman/src/ui/validity_frame.rs diff --git a/pubsubman/src/ui/mod.rs b/pubsubman/src/ui/mod.rs index d87b678..bcf54bd 100644 --- a/pubsubman/src/ui/mod.rs +++ b/pubsubman/src/ui/mod.rs @@ -2,6 +2,7 @@ mod messages_view; mod modal; mod publish_view; mod topic_name; +mod validity_frame; pub use messages_view::MessagesView; pub use modal::Modal; diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view.rs index c999fc2..47dd1e4 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view.rs @@ -8,6 +8,8 @@ use tokio::sync::mpsc::Sender; use crate::actions::publish_message; +use super::validity_frame::ValidityFrame; + #[derive(Default)] pub struct PublishView { data: String, @@ -168,28 +170,3 @@ fn key_count_map(ctx: &egui::Context, attributes: &Attributes) -> HashMap egui::Frame; -} - -impl ValidityFrame for &mut egui::Ui { - fn validity_frame(&self, is_valid: bool) -> egui::Frame { - let (stroke, rounding) = if is_valid { - (egui::Stroke::NONE, egui::Rounding::ZERO) - } else { - ( - egui::Stroke { - width: 1.0, - color: self.visuals().error_fg_color, - }, - self.visuals().widgets.hovered.rounding, - ) - }; - - egui::Frame::none() - .stroke(stroke) - .inner_margin(2.0) - .rounding(rounding) - } -} diff --git a/pubsubman/src/ui/validity_frame.rs b/pubsubman/src/ui/validity_frame.rs new file mode 100644 index 0000000..2970cef --- /dev/null +++ b/pubsubman/src/ui/validity_frame.rs @@ -0,0 +1,24 @@ +pub trait ValidityFrame { + fn validity_frame(&self, is_valid: bool) -> egui::Frame; +} + +impl ValidityFrame for &mut egui::Ui { + fn validity_frame(&self, is_valid: bool) -> egui::Frame { + let (stroke, rounding) = if is_valid { + (egui::Stroke::NONE, egui::Rounding::ZERO) + } else { + ( + egui::Stroke { + width: 1.0, + color: self.visuals().error_fg_color, + }, + self.visuals().widgets.hovered.rounding, + ) + }; + + egui::Frame::none() + .stroke(stroke) + .inner_margin(2.0) + .rounding(rounding) + } +} From 76c0917e3e60014b47bfeda0fdc2be6188d43c76 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 18:31:32 +0100 Subject: [PATCH 7/9] Module restructure. --- pubsubman/src/ui/publish_view/attributes.rs | 71 ++++++++++++++++++ .../{publish_view.rs => publish_view/mod.rs} | 73 ++----------------- 2 files changed, 76 insertions(+), 68 deletions(-) create mode 100644 pubsubman/src/ui/publish_view/attributes.rs rename pubsubman/src/ui/{publish_view.rs => publish_view/mod.rs} (64%) diff --git a/pubsubman/src/ui/publish_view/attributes.rs b/pubsubman/src/ui/publish_view/attributes.rs new file mode 100644 index 0000000..9db215c --- /dev/null +++ b/pubsubman/src/ui/publish_view/attributes.rs @@ -0,0 +1,71 @@ +use std::collections::HashMap; + +use crate::ui::validity_frame::ValidityFrame; + +#[derive(Default, Hash)] +pub struct Attributes(Vec<(String, String)>); + +impl Attributes { + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + pub fn push(&mut self, attr: (String, String)) { + self.0.push(attr); + } + + pub fn show(&mut self, ui: &mut egui::Ui, is_key_valid: impl Fn(&str) -> bool) { + let mut attr_idx_to_delete = None; + + for (idx, (key, val)) in self.0.iter_mut().enumerate() { + let is_valid = is_key_valid(key); + + ui.validity_frame(is_valid).show(ui, |ui| { + ui.add( + egui::TextEdit::singleline(key) + .desired_width(100.0) + .code_editor() + .hint_text("Key"), + ); + }); + + ui.add( + egui::TextEdit::singleline(val) + .desired_width(100.0) + .code_editor() + .hint_text("Value"), + ); + + if ui.button("🗑").clicked() { + attr_idx_to_delete = Some(idx); + } + + ui.end_row(); + } + + if let Some(i) = attr_idx_to_delete { + self.0.remove(i); + } + } +} + +impl From<&Attributes> for HashMap { + fn from(value: &Attributes) -> Self { + HashMap::from_iter(value.0.clone()) + } +} + +#[derive(Default)] +pub struct AttributesKeyCounter; + +impl AttributesKeyCounter { + pub fn key_count_map(&self, attributes: &Attributes) -> HashMap { + let mut key_count_map = HashMap::new(); + + for (key, _) in attributes.0.iter() { + *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; + } + + key_count_map + } +} diff --git a/pubsubman/src/ui/publish_view.rs b/pubsubman/src/ui/publish_view/mod.rs similarity index 64% rename from pubsubman/src/ui/publish_view.rs rename to pubsubman/src/ui/publish_view/mod.rs index 47dd1e4..ba91330 100644 --- a/pubsubman/src/ui/publish_view.rs +++ b/pubsubman/src/ui/publish_view/mod.rs @@ -6,9 +6,11 @@ use pubsubman_backend::{ }; use tokio::sync::mpsc::Sender; -use crate::actions::publish_message; +use crate::{actions::publish_message, ui::publish_view::attributes::AttributesKeyCounter}; -use super::validity_frame::ValidityFrame; +use self::attributes::Attributes; + +mod attributes; #[derive(Default)] pub struct PublishView { @@ -85,72 +87,7 @@ impl PublishView { impl From<&mut PublishView> for PubsubMessageToPublish { fn from(val: &mut PublishView) -> Self { - Self::new( - val.data.clone(), - HashMap::from_iter(val.attributes.0.clone()), - ) - } -} - -#[derive(Default, Hash)] -struct Attributes(Vec<(String, String)>); - -impl Attributes { - fn is_empty(&self) -> bool { - self.0.is_empty() - } - - fn push(&mut self, attr: (String, String)) { - self.0.push(attr); - } - - fn show(&mut self, ui: &mut egui::Ui, is_key_valid: impl Fn(&str) -> bool) { - let mut attr_idx_to_delete = None; - - for (idx, (key, val)) in self.0.iter_mut().enumerate() { - let is_valid = is_key_valid(key); - - ui.validity_frame(is_valid).show(ui, |ui| { - ui.add( - egui::TextEdit::singleline(key) - .desired_width(100.0) - .code_editor() - .hint_text("Key"), - ); - }); - - ui.add( - egui::TextEdit::singleline(val) - .desired_width(100.0) - .code_editor() - .hint_text("Value"), - ); - - if ui.button("🗑").clicked() { - attr_idx_to_delete = Some(idx); - } - - ui.end_row(); - } - - if let Some(i) = attr_idx_to_delete { - self.0.remove(i); - } - } -} - -#[derive(Default)] -struct AttributesKeyCounter; - -impl AttributesKeyCounter { - fn key_count_map(&self, attributes: &Attributes) -> HashMap { - let mut key_count_map = HashMap::new(); - - for (key, _) in attributes.0.iter() { - *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; - } - - key_count_map + Self::new(val.data.clone(), (&val.attributes).into()) } } From 8c33a99db3180f0b14b012005ff8e61d2c98c672 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Sun, 8 Oct 2023 18:59:03 +0100 Subject: [PATCH 8/9] Encapsulated validation logic in AttributesValidator. --- pubsubman/src/ui/publish_view/attributes.rs | 43 ++++++++++++++++----- pubsubman/src/ui/publish_view/mod.rs | 34 +++------------- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/pubsubman/src/ui/publish_view/attributes.rs b/pubsubman/src/ui/publish_view/attributes.rs index 9db215c..5bb2fd8 100644 --- a/pubsubman/src/ui/publish_view/attributes.rs +++ b/pubsubman/src/ui/publish_view/attributes.rs @@ -6,6 +6,16 @@ use crate::ui::validity_frame::ValidityFrame; pub struct Attributes(Vec<(String, String)>); impl Attributes { + fn validator(&self) -> AttributesValidator { + let mut key_count_map = HashMap::new(); + + for (key, _) in self.0.iter() { + *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; + } + + AttributesValidator(key_count_map) + } + pub fn is_empty(&self) -> bool { self.0.is_empty() } @@ -55,17 +65,32 @@ impl From<&Attributes> for HashMap { } } -#[derive(Default)] -pub struct AttributesKeyCounter; +#[derive(Default, Clone)] +pub struct AttributesValidator(HashMap); -impl AttributesKeyCounter { - pub fn key_count_map(&self, attributes: &Attributes) -> HashMap { - let mut key_count_map = HashMap::new(); +impl AttributesValidator { + pub fn is_valid(&self) -> bool { + self.0.iter().all(|(_, count)| *count < 2) + } - for (key, _) in attributes.0.iter() { - *key_count_map.entry(key.clone()).or_insert_with(|| 0) += 1; - } + pub fn is_key_valid(&self, key: &str) -> bool { + self.0.get(key).is_some_and(|count| *count < 2) + } +} - key_count_map +pub fn attributes_validator(ctx: &egui::Context, attributes: &Attributes) -> AttributesValidator { + impl egui::util::cache::ComputerMut<&Attributes, AttributesValidator> for AttributesValidator { + fn compute(&mut self, attributes: &Attributes) -> AttributesValidator { + attributes.validator() + } } + + type AttributesKeyCounterCache = + egui::util::cache::FrameCache; + + ctx.memory_mut(|mem| { + mem.caches + .cache::() + .get(attributes) + }) } diff --git a/pubsubman/src/ui/publish_view/mod.rs b/pubsubman/src/ui/publish_view/mod.rs index ba91330..82b4ff4 100644 --- a/pubsubman/src/ui/publish_view/mod.rs +++ b/pubsubman/src/ui/publish_view/mod.rs @@ -1,14 +1,12 @@ -use std::collections::HashMap; - use pubsubman_backend::{ message::FrontendMessage, model::{PubsubMessageToPublish, TopicName}, }; use tokio::sync::mpsc::Sender; -use crate::{actions::publish_message, ui::publish_view::attributes::AttributesKeyCounter}; +use crate::actions::publish_message; -use self::attributes::Attributes; +use self::attributes::{attributes_validator, Attributes}; mod attributes; @@ -40,8 +38,8 @@ impl PublishView { }); let mut header_text = egui::RichText::new("Attributes"); - let attributes_key_count_map = key_count_map(ui.ctx(), &self.attributes); - let all_attributes_valid = attributes_key_count_map.iter().all(|(_, count)| *count < 2); + let attributes_validator = attributes_validator(ui.ctx(), &self.attributes); + let all_attributes_valid = attributes_validator.is_valid(); if !all_attributes_valid { header_text = header_text.color(ui.visuals().error_fg_color); @@ -57,11 +55,8 @@ impl PublishView { .num_columns(3) .spacing((0.0, 4.0)) .show(ui, |ui| { - self.attributes.show(ui, |key| { - attributes_key_count_map - .get(key) - .is_some_and(|count| *count < 2) - }); + self.attributes + .show(ui, |key| attributes_validator.is_key_valid(key)); }); } @@ -90,20 +85,3 @@ impl From<&mut PublishView> for PubsubMessageToPublish { Self::new(val.data.clone(), (&val.attributes).into()) } } - -fn key_count_map(ctx: &egui::Context, attributes: &Attributes) -> HashMap { - impl egui::util::cache::ComputerMut<&Attributes, HashMap> for AttributesKeyCounter { - fn compute(&mut self, attributes: &Attributes) -> HashMap { - self.key_count_map(attributes) - } - } - - type AttributesKeyCounterCache = - egui::util::cache::FrameCache, AttributesKeyCounter>; - - ctx.memory_mut(|mem| { - mem.caches - .cache::() - .get(attributes) - }) -} From 5522a82ba18e9ca5b826e0432bde101c7c826161 Mon Sep 17 00:00:00 2001 From: dmackdev Date: Tue, 10 Oct 2023 18:39:49 +0100 Subject: [PATCH 9/9] Remove rust-toolchain action to let GH Workflows honour toolchain file. --- .github/workflows/rust.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 8904fca..90dba6c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -14,11 +14,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - uses: actions-rs/cargo@v1 with: command: check @@ -29,11 +24,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - run: sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev - uses: actions-rs/cargo@v1 with: @@ -45,12 +35,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - components: rustfmt - uses: actions-rs/cargo@v1 with: command: fmt @@ -61,12 +45,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - components: clippy - uses: actions-rs/cargo@v1 with: command: clippy