diff --git a/src/networking/types/combobox_data_states.rs b/src/networking/types/combobox_data_states.rs index 682be7ed..9bc4a227 100644 --- a/src/networking/types/combobox_data_states.rs +++ b/src/networking/types/combobox_data_states.rs @@ -4,6 +4,7 @@ use std::net::IpAddr; use crate::countries::types::country::Country; use crate::networking::types::host::Host; use crate::report::types::search_parameters::SearchParameters; +use crate::utils::types::case_insensitive_string::CaseInsensitiveString; use iced::widget::combo_box; use listeners::Process; @@ -23,7 +24,7 @@ impl ComboboxDataStates { if data.domains.1 { states.domains = combo_box::State::with_selection( - data.domains.0.iter().cloned().collect(), + data.domains.0.iter().map(|c| c.0.clone()).collect(), Some(&search.domain), ); data.domains.1 = false; @@ -31,7 +32,7 @@ impl ComboboxDataStates { if data.asns.1 { states.asns = combo_box::State::with_selection( - data.asns.0.iter().cloned().collect(), + data.asns.0.iter().map(|c| c.0.clone()).collect(), Some(&search.as_name), ); data.asns.1 = false; @@ -39,7 +40,7 @@ impl ComboboxDataStates { if data.countries.1 { states.countries = combo_box::State::with_selection( - data.countries.0.iter().cloned().collect(), + data.countries.0.iter().map(|c| c.0.clone()).collect(), Some(&search.country), ); data.countries.1 = false; @@ -47,7 +48,7 @@ impl ComboboxDataStates { if data.programs.1 { states.programs = combo_box::State::with_selection( - data.programs.0.iter().cloned().collect(), + data.programs.0.iter().map(|c| c.0.clone()).collect(), Some(&search.program), ); data.programs.1 = false; @@ -57,25 +58,36 @@ impl ComboboxDataStates { #[derive(Default)] pub struct ComboboxData { - pub domains: (BTreeSet, bool), - pub asns: (BTreeSet, bool), - pub countries: (BTreeSet, bool), - pub programs: (BTreeSet, bool), + pub domains: (BTreeSet, bool), + pub asns: (BTreeSet, bool), + pub countries: (BTreeSet, bool), + pub programs: (BTreeSet, bool), } impl ComboboxData { pub fn update_host(&mut self, host: &Host) { if !host.domain.is_empty() && host.domain.parse::().is_err() { - self.domains.1 = self.domains.0.insert(host.domain.clone()) || self.domains.1; + self.domains.1 = self + .domains + .0 + .insert(CaseInsensitiveString(host.domain.clone())) + || self.domains.1; } if !host.asn.name.is_empty() { - self.asns.1 = self.asns.0.insert(host.asn.name.clone()) || self.asns.1; + self.asns.1 = self + .asns + .0 + .insert(CaseInsensitiveString(host.asn.name.clone())) + || self.asns.1; } if host.country != Country::ZZ { - self.countries.1 = - self.countries.0.insert(host.country.to_string()) || self.countries.1; + self.countries.1 = self + .countries + .0 + .insert(CaseInsensitiveString(host.country.to_string())) + || self.countries.1; } } @@ -83,7 +95,11 @@ impl ComboboxData { if let Some(program) = program && !program.name.is_empty() { - self.programs.1 = self.programs.0.insert(program.name.clone()) || self.programs.1; + self.programs.1 = self + .programs + .0 + .insert(CaseInsensitiveString(program.name.clone())) + || self.programs.1; } } } diff --git a/src/utils/types/case_insensitive_string.rs b/src/utils/types/case_insensitive_string.rs new file mode 100644 index 00000000..b0e9b764 --- /dev/null +++ b/src/utils/types/case_insensitive_string.rs @@ -0,0 +1,24 @@ +#[derive(Clone)] +/// A wrapper around String that compares case-insensitively. +/// Used in comboboxes dropdown lists to sort them case-insensitively. +pub struct CaseInsensitiveString(pub String); + +impl Ord for CaseInsensitiveString { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.to_lowercase().cmp(&other.0.to_lowercase()) + } +} + +impl PartialOrd for CaseInsensitiveString { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for CaseInsensitiveString { + fn eq(&self, other: &Self) -> bool { + self.0.to_lowercase() == other.0.to_lowercase() + } +} + +impl Eq for CaseInsensitiveString {} diff --git a/src/utils/types/mod.rs b/src/utils/types/mod.rs index 902ef8ee..5a14a200 100644 --- a/src/utils/types/mod.rs +++ b/src/utils/types/mod.rs @@ -1,3 +1,4 @@ +pub mod case_insensitive_string; pub mod file_info; pub mod icon; pub mod timestamp;