add bits data representation WIP (replace ChartType with DataRepr)

This commit is contained in:
GyulyVGC
2025-08-14 00:23:30 +02:00
parent 2a0103c05c
commit bc5bb0ae21
22 changed files with 235 additions and 239 deletions

View File

@@ -310,7 +310,7 @@ fn test_chart_data_updates() {
min_packets: -1000.0,
max_packets: 21000.0,
language: Language::default(),
chart_type: ChartType::Packets,
data_repr: ChartType::Packets,
style: StyleType::default(),
thumbnail: false,
is_live_capture: true,

View File

@@ -1,21 +0,0 @@
use crate::Language;
use crate::translations::translations::{bytes_translation, packets_translation};
use serde::{Deserialize, Serialize};
/// Enum representing the possible kind of chart displayed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ChartType {
Packets,
Bytes,
}
impl ChartType {
pub(crate) const ALL: [ChartType; 2] = [ChartType::Bytes, ChartType::Packets];
pub fn get_label(&self, language: Language) -> &str {
match self {
ChartType::Packets => packets_translation(language),
ChartType::Bytes => bytes_translation(language),
}
}
}

View File

@@ -1,7 +1,6 @@
use crate::chart::types::chart_type::ChartType;
use crate::gui::styles::donut::Catalog;
use crate::gui::styles::style_constants::{FONT_SIZE_FOOTER, FONT_SIZE_SUBTITLE};
use crate::networking::types::byte_multiple::ByteMultiple;
use crate::networking::types::data_representation::DataRepr;
use iced::alignment::{Horizontal, Vertical};
use iced::widget::canvas::path::Arc;
use iced::widget::canvas::{Frame, Text};
@@ -10,7 +9,7 @@
use std::f32::consts;
pub struct DonutChart {
chart_type: ChartType,
data_repr: DataRepr,
incoming: u128,
outgoing: u128,
filtered_out: u128,
@@ -21,7 +20,7 @@ pub struct DonutChart {
impl DonutChart {
fn new(
chart_type: ChartType,
data_repr: DataRepr,
incoming: u128,
outgoing: u128,
filtered_out: u128,
@@ -30,7 +29,7 @@ fn new(
thumbnail: bool,
) -> Self {
Self {
chart_type,
data_repr,
incoming,
outgoing,
filtered_out,
@@ -46,11 +45,7 @@ fn total(&self) -> u128 {
fn title(&self) -> String {
let total = self.total();
if self.chart_type.eq(&ChartType::Bytes) {
ByteMultiple::formatted_string(total)
} else {
total.to_string()
}
self.data_repr.formatted_string(total)
}
fn angles(&self) -> [(Radians, Radians); 4] {
@@ -150,7 +145,7 @@ fn draw(
}
pub fn donut_chart<Message, Theme: Catalog>(
chart_type: ChartType,
data_repr: DataRepr,
incoming: u128,
outgoing: u128,
filtered_out: u128,
@@ -164,7 +159,7 @@ pub fn donut_chart<Message, Theme: Catalog>(
Length::Fixed(110.0)
};
iced::widget::canvas(DonutChart::new(
chart_type,
data_repr,
incoming,
outgoing,
filtered_out,

View File

@@ -1,3 +1,2 @@
pub mod chart_type;
pub mod donut_chart;
pub mod traffic_chart;

View File

@@ -15,12 +15,13 @@
use crate::gui::styles::style_constants::CHARTS_LINE_BORDER;
use crate::gui::styles::types::palette::to_rgb_color;
use crate::gui::types::message::Message;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::traffic_direction::TrafficDirection;
use crate::translations::translations::{incoming_translation, outgoing_translation};
use crate::utils::error_logger::{ErrorLogger, Location};
use crate::utils::formatted_strings::{get_formatted_num_seconds, get_formatted_timestamp};
use crate::utils::types::timestamp::Timestamp;
use crate::{ByteMultiple, ChartType, Language, StyleType, location};
use crate::{Language, StyleType, location};
/// Struct defining the chart to be displayed in gui run page
pub struct TrafficChart {
@@ -45,7 +46,7 @@ pub struct TrafficChart {
/// Language used for the chart legend
pub language: Language,
/// Packets or bytes
pub chart_type: ChartType,
pub data_repr: DataRepr,
/// Style of the chart
pub style: StyleType,
/// Whether the chart is for the thumbnail page
@@ -71,7 +72,7 @@ pub fn new(style: StyleType, language: Language) -> Self {
min_packets: 0.0,
max_packets: 0.0,
language,
chart_type: ChartType::Bytes,
data_repr: DataRepr::Bytes,
style,
thumbnail: false,
is_live_capture: true,
@@ -115,8 +116,8 @@ pub fn view(&self) -> Element<'_, Message, StyleType> {
.into()
}
pub fn change_kind(&mut self, kind: ChartType) {
self.chart_type = kind;
pub fn change_kind(&mut self, kind: DataRepr) {
self.data_repr = kind;
}
pub fn change_language(&mut self, language: Language) {
@@ -169,7 +170,7 @@ fn x_axis_range(&self) -> Range<f32> {
}
fn y_axis_range(&self) -> Range<f32> {
let (min, max) = match self.chart_type {
let (min, max) = match self.data_repr {
ChartType::Packets => (self.min_packets, self.max_packets),
ChartType::Bytes => (self.min_bytes, self.max_bytes),
};
@@ -186,7 +187,7 @@ fn font<'a>(&self, size: f64) -> TextStyle<'a> {
}
fn spline_to_plot(&self, direction: TrafficDirection) -> &Spline<f32, f32> {
match self.chart_type {
match self.data_repr {
ChartType::Packets => match direction {
TrafficDirection::Incoming => &self.in_packets.spline,
TrafficDirection::Outgoing => &self.out_packets.spline,
@@ -283,12 +284,10 @@ fn build_chart<DB: DrawingBackend>(
.max_light_lines(0)
.label_style(self.font(12.5))
.y_labels(min(5, y_labels))
.y_label_formatter(if self.chart_type.eq(&ChartType::Packets) {
&|packets| packets.abs().to_string()
} else {
.y_label_formatter(
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
&|bytes| ByteMultiple::formatted_string(bytes.abs() as u128)
})
&|amount| self.data_repr.formatted_string(amount.abs() as u128),
)
.x_labels(min(6, x_labels))
.x_label_formatter(
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]

View File

@@ -11,7 +11,6 @@
};
use iced::{Alignment, Font, Length, Padding, Pixels, alignment};
use crate::chart::types::chart_type::ChartType;
use crate::gui::components::tab::get_pages_tabs;
use crate::gui::components::types::my_modal::MyModal;
use crate::gui::pages::overview_page::{get_bars, get_bars_length};
@@ -23,8 +22,8 @@
use crate::gui::styles::text_input::TextInputType;
use crate::gui::types::message::Message;
use crate::networking::types::address_port_pair::AddressPortPair;
use crate::networking::types::byte_multiple::ByteMultiple;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_representation::{ByteMultiple, DataRepr};
use crate::networking::types::host_data_states::HostStates;
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
use crate::networking::types::traffic_direction::TrafficDirection;
@@ -144,7 +143,7 @@ fn report<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
.push(get_agglomerates_row(
font,
agglomerate,
sniffer.traffic_chart.chart_type,
sniffer.traffic_chart.data_repr,
))
.push(Rule::horizontal(5))
.push(get_change_page_row(
@@ -550,12 +549,12 @@ fn get_button_change_page<'a>(increment: bool) -> Button<'a, Message, StyleType>
fn get_agglomerates_row<'a>(
font: Font,
tot: DataInfo,
chart_type: ChartType,
data_repr: DataRepr,
) -> Row<'a, Message, StyleType> {
let tot_packets = tot.tot_packets();
let tot_bytes = tot.tot_bytes();
let (in_length, out_length) = get_bars_length(chart_type, &tot, &tot);
let (in_length, out_length) = get_bars_length(data_repr, &tot, &tot);
let bars = get_bars(in_length, out_length).width(ReportCol::FILTER_COLUMNS_WIDTH);
let bytes_col = Column::new()

View File

@@ -1,4 +1,3 @@
use crate::chart::types::chart_type::ChartType;
use crate::countries::country_utils::get_computer_tooltip;
use crate::countries::flags_pictures::FLAGS_HEIGHT_BIG;
use crate::gui::components::header::get_button_settings;
@@ -13,6 +12,7 @@
use crate::gui::types::message::Message;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::Host;
use crate::networking::types::service::Service;
use crate::networking::types::traffic_type::TrafficType;
@@ -21,13 +21,12 @@
};
use crate::report::types::sort_type::SortType;
use crate::translations::translations::{
bytes_exceeded_translation, clear_all_translation, favorite_transmitted_translation,
no_notifications_received_translation, no_notifications_set_translation,
only_last_30_translation, packets_exceeded_translation, per_second_translation,
clear_all_translation, favorite_transmitted_translation, no_notifications_received_translation,
no_notifications_set_translation, only_last_30_translation, per_second_translation,
threshold_translation,
};
use crate::utils::types::icon::Icon;
use crate::{ByteMultiple, ConfigSettings, Language, RunningPage, Sniffer, StyleType};
use crate::{ConfigSettings, Language, RunningPage, Sniffer, StyleType};
use iced::Length::FillPortion;
use iced::widget::scrollable::Direction;
use iced::widget::text::LineHeight;
@@ -150,13 +149,9 @@ fn data_notification_log<'a>(
language: Language,
font: Font,
) -> Container<'a, Message, StyleType> {
let chart_type = logged_notification.chart_type;
let data_string = if chart_type == ChartType::Bytes {
ByteMultiple::formatted_string(logged_notification.threshold.into())
} else {
logged_notification.threshold.to_string()
};
let icon = if chart_type == ChartType::Packets {
let data_repr = logged_notification.data_repr;
let data_string = data_repr.formatted_string(logged_notification.threshold.into());
let icon = if data_repr == DataRepr::Packets {
Icon::PacketsThreshold
} else {
Icon::BytesThreshold
@@ -184,13 +179,9 @@ fn data_notification_log<'a>(
.push(Text::new(logged_notification.timestamp.clone()).font(font)),
)
.push(
Text::new(if chart_type == ChartType::Bytes {
bytes_exceeded_translation(language)
} else {
packets_exceeded_translation(language)
})
.class(TextType::Title)
.font(font),
Text::new(data_repr.data_exceeded_translation(language))
.class(TextType::Title)
.font(font),
)
.push(
Text::new(threshold_str)
@@ -222,14 +213,14 @@ fn data_notification_log<'a>(
fn favorite_notification_log<'a>(
logged_notification: &FavoriteTransmitted,
first_entry_data_info: DataInfo,
chart_type: ChartType,
data_repr: DataRepr,
language: Language,
font: Font,
) -> Container<'a, Message, StyleType> {
let host_bar = host_bar(
&logged_notification.host,
&logged_notification.data_info_host,
chart_type,
data_repr,
first_entry_data_info,
font,
language,
@@ -294,7 +285,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
let ConfigSettings {
style, language, ..
} = sniffer.configs.settings;
let chart_type = sniffer.traffic_chart.chart_type;
let data_repr = sniffer.traffic_chart.data_repr;
let font = style.get_extension().font;
let mut ret_val = Column::new()
.padding(Padding::ZERO.right(15))
@@ -306,7 +297,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
.0
.iter()
.map(LoggedNotification::data_info)
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
.unwrap_or_default();
for logged_notification in &sniffer.logged_notifications.0 {
@@ -323,7 +314,7 @@ fn logged_notifications<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType>
favorite_notification_log(
favorite_transmitted,
first_entry_data_info,
chart_type,
data_repr,
language,
font,
)
@@ -339,10 +330,10 @@ fn threshold_bar<'a>(
language: Language,
font: Font,
) -> Row<'a, Message, StyleType> {
let chart_type = logged_notification.chart_type;
let data_repr = logged_notification.data_repr;
let data_info = logged_notification.data_info;
let (incoming_bar_len, outgoing_bar_len) =
get_bars_length(chart_type, &first_entry_data_info, &data_info);
get_bars_length(data_repr, &first_entry_data_info, &data_info);
Row::new()
.align_y(Alignment::Center)
@@ -358,16 +349,9 @@ fn threshold_bar<'a>(
.push(
Column::new()
.spacing(1)
.push(
Row::new().push(horizontal_space()).push(
Text::new(if chart_type.eq(&ChartType::Packets) {
data_info.tot_packets().to_string()
} else {
ByteMultiple::formatted_string(data_info.tot_bytes())
})
.font(font),
),
)
.push(Row::new().push(horizontal_space()).push(
Text::new(data_repr.formatted_string_from_data_info(&data_info)).font(font),
))
.push(get_bars(incoming_bar_len, outgoing_bar_len)),
)
}
@@ -424,7 +408,7 @@ fn data_notification_extra<'a>(
let host_bar = host_bar(
host,
data_info_host,
logged_notification.chart_type,
logged_notification.data_repr,
first_data_info_host,
font,
language,
@@ -442,7 +426,7 @@ fn data_notification_extra<'a>(
let service_bar = service_bar(
service,
data_info,
logged_notification.chart_type,
logged_notification.data_repr,
first_data_info_service,
font,
);

View File

@@ -19,6 +19,7 @@
use crate::networking::types::capture_context::CaptureSource;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::filters::Filters;
use crate::networking::types::host::Host;
use crate::networking::types::service::Service;
@@ -38,7 +39,7 @@
use crate::translations::translations_4::{excluded_translation, reading_from_pcap_translation};
use crate::utils::formatted_strings::get_active_filters_string;
use crate::utils::types::icon::Icon;
use crate::{ByteMultiple, ChartType, ConfigSettings, Language, RunningPage, StyleType};
use crate::{ConfigSettings, Language, RunningPage, StyleType};
use iced::Length::{Fill, FillPortion};
use iced::alignment::{Horizontal, Vertical};
use iced::widget::scrollable::Direction;
@@ -245,16 +246,16 @@ fn col_host<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
style, language, ..
} = sniffer.configs.settings;
let font = style.get_extension().font;
let chart_type = sniffer.traffic_chart.chart_type;
let data_repr = sniffer.traffic_chart.data_repr;
let mut scroll_host = Column::new()
.padding(Padding::ZERO.right(11.0))
.align_x(Alignment::Center);
let entries = get_host_entries(&sniffer.info_traffic, chart_type, sniffer.host_sort_type);
let entries = get_host_entries(&sniffer.info_traffic, data_repr, sniffer.host_sort_type);
let first_entry_data_info = entries
.iter()
.map(|(_, d)| d.data_info)
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
.unwrap_or_default();
for (host, data_info_host) in &entries {
@@ -263,7 +264,7 @@ fn col_host<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
let host_bar = host_bar(
host,
data_info_host,
chart_type,
data_repr,
first_entry_data_info,
font,
language,
@@ -322,20 +323,20 @@ fn col_service<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
style, language, ..
} = sniffer.configs.settings;
let font = style.get_extension().font;
let chart_type = sniffer.traffic_chart.chart_type;
let data_repr = sniffer.traffic_chart.data_repr;
let mut scroll_service = Column::new()
.padding(Padding::ZERO.right(11.0))
.align_x(Alignment::Center);
let entries = get_service_entries(&sniffer.info_traffic, chart_type, sniffer.service_sort_type);
let entries = get_service_entries(&sniffer.info_traffic, data_repr, sniffer.service_sort_type);
let first_entry_data_info = entries
.iter()
.map(|&(_, d)| d)
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, chart_type))
.max_by(|d1, d2| d1.compare(d2, SortType::Ascending, data_repr))
.unwrap_or_default();
for (service, data_info) in &entries {
let content = service_bar(service, data_info, chart_type, first_entry_data_info, font);
let content = service_bar(service, data_info, data_repr, first_entry_data_info, font);
scroll_service = scroll_service.push(
button(content)
@@ -384,16 +385,13 @@ fn col_service<'a>(sniffer: &Sniffer) -> Column<'a, Message, StyleType> {
pub fn host_bar<'a>(
host: &Host,
data_info_host: &DataInfoHost,
chart_type: ChartType,
data_repr: DataRepr,
first_entry_data_info: DataInfo,
font: Font,
language: Language,
) -> Row<'a, Message, StyleType> {
let (incoming_bar_len, outgoing_bar_len) = get_bars_length(
chart_type,
&first_entry_data_info,
&data_info_host.data_info,
);
let (incoming_bar_len, outgoing_bar_len) =
get_bars_length(data_repr, &first_entry_data_info, &data_info_host.data_info);
Row::new()
.height(FLAGS_HEIGHT_BIG)
@@ -422,11 +420,10 @@ pub fn host_bar<'a>(
)
.push(horizontal_space())
.push(
Text::new(if chart_type.eq(&ChartType::Packets) {
data_info_host.data_info.tot_packets().to_string()
} else {
ByteMultiple::formatted_string(data_info_host.data_info.tot_bytes())
})
Text::new(
data_repr
.formatted_string_from_data_info(&data_info_host.data_info),
)
.font(font),
),
)
@@ -437,12 +434,12 @@ pub fn host_bar<'a>(
pub fn service_bar<'a>(
service: &Service,
data_info: &DataInfo,
chart_type: ChartType,
data_repr: DataRepr,
first_entry_data_info: DataInfo,
font: Font,
) -> Row<'a, Message, StyleType> {
let (incoming_bar_len, outgoing_bar_len) =
get_bars_length(chart_type, &first_entry_data_info, data_info);
get_bars_length(data_repr, &first_entry_data_info, data_info);
Row::new()
.height(FLAGS_HEIGHT_BIG)
@@ -456,12 +453,8 @@ pub fn service_bar<'a>(
.push(Text::new(service.to_string()).font(font))
.push(horizontal_space())
.push(
Text::new(if chart_type.eq(&ChartType::Packets) {
data_info.tot_packets().to_string()
} else {
ByteMultiple::formatted_string(data_info.tot_bytes())
})
.font(font),
Text::new(data_repr.formatted_string_from_data_info(&data_info))
.font(font),
),
)
.push(get_bars(incoming_bar_len, outgoing_bar_len)),
@@ -477,7 +470,7 @@ fn col_info<'a>(sniffer: &Sniffer) -> Container<'a, Message, StyleType> {
let col_device = col_device(language, font, &sniffer.capture_source);
let col_data_representation =
col_data_representation(language, font, sniffer.traffic_chart.chart_type);
col_data_representation(language, font, sniffer.traffic_chart.data_repr);
let donut_row = donut_row(language, font, sniffer);
@@ -555,7 +548,7 @@ fn col_device<'a>(
fn col_data_representation<'a>(
language: Language,
font: Font,
chart_type: ChartType,
data_repr: DataRepr,
) -> Column<'a, Message, StyleType> {
let mut ret_val = Column::new().spacing(5).push(
Text::new(format!("{}:", data_representation_translation(language)))
@@ -564,7 +557,7 @@ fn col_data_representation<'a>(
);
for option in ChartType::ALL {
let is_active = chart_type.eq(&option);
let is_active = data_repr.eq(&option);
ret_val = ret_val.push(
Button::new(
Text::new(option.get_label(language).to_owned())
@@ -580,7 +573,7 @@ fn col_data_representation<'a>(
} else {
ButtonType::BorderedRound
})
.on_press(Message::ChartSelection(option)),
.on_press(Message::DataReprSelection(option)),
);
}
ret_val
@@ -591,18 +584,18 @@ fn donut_row<'a>(
font: Font,
sniffer: &Sniffer,
) -> Container<'a, Message, StyleType> {
let chart_type = sniffer.traffic_chart.chart_type;
let data_repr = sniffer.traffic_chart.data_repr;
let filters = &sniffer.filters;
let (in_data, out_data, filtered_out, dropped) =
sniffer.info_traffic.get_thumbnail_data(chart_type);
sniffer.info_traffic.get_thumbnail_data(data_repr);
let legend_entry_filtered = if filters.none_active() {
None
} else {
Some(donut_legend_entry(
filtered_out,
chart_type,
data_repr,
RuleType::FilteredOut,
filters,
font,
@@ -614,7 +607,7 @@ fn donut_row<'a>(
.spacing(5)
.push(donut_legend_entry(
in_data,
chart_type,
data_repr,
RuleType::Incoming,
filters,
font,
@@ -622,7 +615,7 @@ fn donut_row<'a>(
))
.push(donut_legend_entry(
out_data,
chart_type,
data_repr,
RuleType::Outgoing,
filters,
font,
@@ -631,7 +624,7 @@ fn donut_row<'a>(
.push_maybe(legend_entry_filtered)
.push(donut_legend_entry(
dropped,
chart_type,
data_repr,
RuleType::Dropped,
filters,
font,
@@ -642,7 +635,7 @@ fn donut_row<'a>(
.align_y(Vertical::Center)
.spacing(20)
.push(donut_chart(
chart_type,
data_repr,
in_data,
out_data,
filtered_out,
@@ -661,17 +654,13 @@ fn donut_row<'a>(
fn donut_legend_entry<'a>(
value: u128,
chart_type: ChartType,
data_repr: DataRepr,
rule_type: RuleType,
filters: &Filters,
font: Font,
language: Language,
) -> Row<'a, Message, StyleType> {
let value_text = if chart_type.eq(&ChartType::Bytes) {
ByteMultiple::formatted_string(value)
} else {
value.to_string()
};
let value_text = data_repr.formatted_string(value);
let label = match rule_type {
RuleType::Incoming => incoming_translation(language),
@@ -702,11 +691,11 @@ fn donut_legend_entry<'a>(
const MIN_BARS_LENGTH: f32 = 4.0;
pub fn get_bars_length(
chart_type: ChartType,
data_repr: DataRepr,
first_entry: &DataInfo,
data_info: &DataInfo,
) -> (u16, u16) {
let (in_val, out_val, first_entry_tot_val) = match chart_type {
let (in_val, out_val, first_entry_tot_val) = match data_repr {
ChartType::Packets => (
data_info.incoming_packets(),
data_info.outgoing_packets(),
@@ -881,7 +870,6 @@ fn sort_arrows<'a>(
#[cfg(test)]
mod tests {
use crate::chart::types::chart_type::ChartType;
use crate::gui::pages::overview_page::{MIN_BARS_LENGTH, get_bars_length};
use crate::networking::types::data_info::DataInfo;

View File

@@ -3,7 +3,6 @@
use iced::widget::{Checkbox, Column, Container, Row, Scrollable, Space, Text, TextInput};
use iced::{Alignment, Font, Length, Padding};
use crate::chart::types::chart_type::ChartType;
use crate::gui::components::button::button_hide;
use crate::gui::components::tab::get_settings_tabs;
use crate::gui::pages::types::settings_page::SettingsPage;
@@ -14,6 +13,7 @@
use crate::gui::styles::text::TextType;
use crate::gui::styles::types::gradient_type::GradientType;
use crate::gui::types::message::Message;
use crate::networking::types::data_representation::DataRepr;
use crate::notifications::types::notifications::{
DataNotification, FavoriteNotification, Notification,
};
@@ -144,7 +144,7 @@ fn get_data_notify<'a>(
data_notification,
language,
font,
data_notification.chart_type,
data_notification.data_repr,
);
let input_row = input_group_bytes(data_notification, font, language);
let sound_row = sound_buttons(Notification::Data(data_notification), font, language);
@@ -372,7 +372,7 @@ fn row_data_representation<'a>(
data_notification: DataNotification,
language: Language,
font: Font,
chart_type: ChartType,
data_repr: DataRepr,
) -> Row<'a, Message, StyleType> {
let mut ret_val = Row::new()
.width(Length::Shrink)
@@ -381,8 +381,8 @@ fn row_data_representation<'a>(
.push(Space::with_width(45))
.push(Text::new(format!("{}:", data_representation_translation(language))).font(font));
for option in ChartType::ALL {
let is_active = chart_type.eq(&option);
for option in DataRepr::ALL {
let is_active = data_repr.eq(&option);
ret_val = ret_val.push(
Button::new(
Text::new(option.get_label(language).to_owned())
@@ -400,7 +400,7 @@ fn row_data_representation<'a>(
})
.on_press(Message::UpdateNotificationSettings(
Notification::Data(DataNotification {
chart_type: option,
data_repr: option,
..data_notification
}),
false,

View File

@@ -4,7 +4,6 @@
use iced::widget::{Column, Container, Row, Rule, Space, Text, vertical_space};
use iced::{Alignment, Font, Length};
use crate::chart::types::chart_type::ChartType;
use crate::chart::types::donut_chart::donut_chart;
use crate::configs::types::config_settings::ConfigSettings;
use crate::countries::country_utils::get_flag_tooltip;
@@ -12,6 +11,7 @@
use crate::gui::styles::style_constants::FONT_SIZE_FOOTER;
use crate::gui::styles::types::style_type::StyleType;
use crate::gui::types::message::Message;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::{Host, ThumbnailHost};
use crate::networking::types::info_traffic::InfoTraffic;
use crate::report::get_report_entries::{get_host_entries, get_service_entries};
@@ -41,16 +41,16 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
}
let info_traffic = &sniffer.info_traffic;
let chart_type = sniffer.traffic_chart.chart_type;
let data_repr = sniffer.traffic_chart.data_repr;
let (in_data, out_data, filtered_out, dropped) = info_traffic.get_thumbnail_data(chart_type);
let (in_data, out_data, filtered_out, dropped) = info_traffic.get_thumbnail_data(data_repr);
let charts = Row::new()
.padding(5)
.height(Length::Fill)
.align_y(Alignment::Center)
.push(donut_chart(
chart_type,
data_repr,
in_data,
out_data,
filtered_out,
@@ -71,14 +71,14 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
.align_y(Alignment::Start)
.push(host_col(
info_traffic,
chart_type,
data_repr,
font,
sniffer.host_sort_type,
))
.push(Rule::vertical(10))
.push(service_col(
info_traffic,
chart_type,
data_repr,
font,
sniffer.service_sort_type,
));
@@ -93,7 +93,7 @@ pub fn thumbnail_page(sniffer: &Sniffer) -> Container<'_, Message, StyleType> {
fn host_col<'a>(
info_traffic: &InfoTraffic,
chart_type: ChartType,
data_repr: DataRepr,
font: Font,
sort_type: SortType,
) -> Column<'a, Message, StyleType> {
@@ -101,7 +101,7 @@ fn host_col<'a>(
.padding([0, 5])
.spacing(3)
.width(Length::FillPortion(2));
let hosts = get_host_entries(info_traffic, chart_type, sort_type);
let hosts = get_host_entries(info_traffic, data_repr, sort_type);
let mut thumbnail_hosts = Vec::new();
for (host, data_info_host) in &hosts {
@@ -136,12 +136,12 @@ fn host_col<'a>(
fn service_col<'a>(
info_traffic: &InfoTraffic,
chart_type: ChartType,
data_repr: DataRepr,
font: Font,
sort_type: SortType,
) -> Column<'a, Message, StyleType> {
let mut service_col = Column::new().padding([0, 5]).spacing(3).width(Length::Fill);
let services = get_service_entries(info_traffic, chart_type, sort_type);
let services = get_service_entries(info_traffic, data_repr, sort_type);
let n_entry = min(services.len(), MAX_ENTRIES);
for (service, _) in services.get(..n_entry).unwrap_or_default() {
service_col = service_col.push(

View File

@@ -304,7 +304,7 @@ pub fn update(&mut self, message: Message) -> Task<Message> {
}
self.filters.port_str = value;
}
Message::ChartSelection(unit) => self.traffic_chart.change_kind(unit),
Message::DataReprSelection(unit) => self.traffic_chart.change_kind(unit),
Message::ReportSortSelection(sort) => {
self.page_number = 1;
self.report_sort_type = sort;
@@ -868,7 +868,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
let notifications = self.configs.settings.notifications;
let sound = match notification {
Notification::Data(DataNotification {
chart_type,
data_repr,
threshold,
byte_multiple,
sound,
@@ -880,7 +880,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
|| temp_threshold.previous_threshold != previous_threshold
{
temp_threshold = DataNotification {
chart_type,
data_repr,
threshold,
byte_multiple,
sound,
@@ -910,7 +910,7 @@ fn update_notifications_settings(&mut self, notification: Notification, emit_sou
.settings
.notifications
.data_notification
.chart_type = chart_type;
.data_repr = data_repr;
sound
}
Notification::Favorite(favorite_notification) => {
@@ -1200,13 +1200,13 @@ fn test_correctly_update_protocol() {
fn test_correctly_update_chart_kind() {
let mut sniffer = Sniffer::new(Configs::default());
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Bytes);
sniffer.update(Message::ChartSelection(ChartType::Packets));
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Packets);
sniffer.update(Message::ChartSelection(ChartType::Packets));
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Packets);
sniffer.update(Message::ChartSelection(ChartType::Bytes));
assert_eq!(sniffer.traffic_chart.chart_type, ChartType::Bytes);
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Bytes);
sniffer.update(Message::DataReprSelection(ChartType::Packets));
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Packets);
sniffer.update(Message::DataReprSelection(ChartType::Packets));
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Packets);
sniffer.update(Message::DataReprSelection(ChartType::Bytes));
assert_eq!(sniffer.traffic_chart.data_repr, ChartType::Bytes);
}
#[test]
@@ -1662,7 +1662,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
let mut sniffer = Sniffer::new(Configs::default());
let bytes_notification_init = DataNotification {
chart_type: ChartType::Bytes,
data_repr: ChartType::Bytes,
threshold: None,
byte_multiple: ByteMultiple::KB,
sound: Sound::Pop,
@@ -1670,7 +1670,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
};
let bytes_notification_toggled_on = DataNotification {
chart_type: ChartType::Bytes,
data_repr: ChartType::Bytes,
threshold: Some(800_000),
byte_multiple: ByteMultiple::GB,
sound: Sound::Pop,
@@ -1678,7 +1678,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
};
let bytes_notification_adjusted_threshold_sound_off = DataNotification {
chart_type: ChartType::Bytes,
data_repr: ChartType::Bytes,
threshold: Some(3),
byte_multiple: ByteMultiple::KB,
sound: Sound::None,
@@ -1686,7 +1686,7 @@ fn expire_notifications_timeout(sniffer: &mut Sniffer) {
};
let bytes_notification_sound_off_only = DataNotification {
chart_type: ChartType::Bytes,
data_repr: ChartType::Bytes,
threshold: Some(800_000),
byte_multiple: ByteMultiple::GB,
sound: Sound::None,
@@ -1806,7 +1806,7 @@ fn test_clear_all_notifications() {
VecDeque::from([LoggedNotification::DataThresholdExceeded(
DataThresholdExceeded {
id: 1,
chart_type: ChartType::Packets,
data_repr: ChartType::Packets,
threshold: 0,
data_info: DataInfo::default(),
timestamp: "".to_string(),

View File

@@ -5,6 +5,7 @@
use crate::gui::pages::types::running_page::RunningPage;
use crate::gui::pages::types::settings_page::SettingsPage;
use crate::gui::styles::types::gradient_type::GradientType;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::{Host, HostMessage};
use crate::networking::types::info_traffic::InfoTraffic;
use crate::notifications::types::notifications::Notification;
@@ -12,7 +13,7 @@
use crate::report::types::sort_type::SortType;
use crate::utils::types::file_info::FileInfo;
use crate::utils::types::web_page::WebPage;
use crate::{ChartType, IpVersion, Language, Protocol, ReportSortType, StyleType};
use crate::{IpVersion, Language, Protocol, ReportSortType, StyleType};
#[derive(Debug, Clone)]
/// Messages types that permit reacting to application interactions/subscriptions
@@ -31,8 +32,8 @@ pub enum Message {
AddressFilter(String),
/// Changed port filter
PortFilter(String),
/// Select chart type to be displayed
ChartSelection(ChartType),
/// Select data representation to use
DataReprSelection(DataRepr),
/// Select report sort type to be displayed (inspect page)
ReportSortSelection(ReportSortType),
/// Select host sort type to be displayed (overview page)

View File

@@ -9,7 +9,6 @@
use iced::window::settings::PlatformSpecific;
use iced::{Font, Pixels, Settings, application, window};
use chart::types::chart_type::ChartType;
use chart::types::traffic_chart::TrafficChart;
use cli::handle_cli_args;
use configs::types::config_device::ConfigDevice;
@@ -18,7 +17,7 @@
use gui::sniffer::Sniffer;
use gui::styles::style_constants::FONT_SIZE_BODY;
use gui::styles::types::style_type::StyleType;
use networking::types::byte_multiple::ByteMultiple;
use networking::types::data_representation::ByteMultiple;
use networking::types::info_traffic::InfoTraffic;
use networking::types::ip_version::IpVersion;
use networking::types::protocol::Protocol;

View File

@@ -1,6 +1,6 @@
//! Module defining the `DataInfo` struct, which represents incoming and outgoing packets and bytes.
use crate::chart::types::chart_type::ChartType;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::traffic_direction::TrafficDirection;
use crate::report::types::sort_type::SortType;
use std::cmp::Ordering;
@@ -47,8 +47,8 @@ pub fn tot_bytes(&self) -> u128 {
self.incoming_bytes + self.outgoing_bytes
}
pub fn tot_data(&self, chart_type: ChartType) -> u128 {
match chart_type {
pub fn tot_data(&self, data_repr: DataRepr) -> u128 {
match data_repr {
ChartType::Packets => self.tot_packets(),
ChartType::Bytes => self.tot_bytes(),
}
@@ -103,8 +103,8 @@ pub fn refresh(&mut self, rhs: Self) {
self.final_instant = rhs.final_instant;
}
pub fn compare(&self, other: &Self, sort_type: SortType, chart_type: ChartType) -> Ordering {
match chart_type {
pub fn compare(&self, other: &Self, sort_type: SortType, data_repr: DataRepr) -> Ordering {
match data_repr {
ChartType::Packets => match sort_type {
SortType::Ascending => self.tot_packets().cmp(&other.tot_packets()),
SortType::Descending => other.tot_packets().cmp(&self.tot_packets()),

View File

@@ -1,8 +1,73 @@
use std::fmt;
use crate::networking::types::data_info::DataInfo;
use crate::translations::translations::{
bytes_exceeded_translation, bytes_translation, packets_exceeded_translation,
packets_translation,
};
use crate::translations::translations_4::{bits_exceeded_translation, bits_translation};
use crate::translations::types::language::Language;
use serde::{Deserialize, Serialize};
/// Enum representing the possible observed values of IP protocol version.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DataRepr {
Packets,
Bytes,
Bits,
}
impl DataRepr {
pub(crate) const ALL: [DataRepr; 3] = [DataRepr::Bits, DataRepr::Bytes, DataRepr::Packets];
pub fn get_label(&self, language: Language) -> &str {
match self {
DataRepr::Packets => packets_translation(language),
DataRepr::Bytes => bytes_translation(language),
DataRepr::Bits => bits_translation(language),
}
}
/// Returns a String representing a quantity of traffic (packets / bytes / bits) with the proper multiple if applicable
pub fn formatted_string(&self, amount: u128) -> String {
if self == &DataRepr::Packets {
return amount.to_string();
}
#[allow(clippy::cast_precision_loss)]
let mut n = amount as f32;
let byte_multiple = ByteMultiple::from_amount(amount);
#[allow(clippy::cast_precision_loss)]
let multiplier = byte_multiple.multiplier() as f32;
n /= multiplier;
if n > 999.0 && byte_multiple != ByteMultiple::PB {
// this allows representing e.g. 999_999 as 999 KB instead of 1000 KB
n = 999.0;
}
let precision = usize::from(byte_multiple != ByteMultiple::B && n <= 9.95);
format!("{n:.precision$} {}", byte_multiple.pretty_print(*self))
.trim()
.to_string()
}
pub fn formatted_string_from_data_info(&self, data_info: &DataInfo) -> String {
let amount = match self {
DataRepr::Packets => data_info.tot_packets(),
DataRepr::Bytes => data_info.tot_bytes(),
DataRepr::Bits => data_info.tot_bytes() * 8,
};
self.formatted_string(amount)
}
pub fn data_exceeded_translation(&self, language: Language) -> &str {
match self {
DataRepr::Packets => packets_exceeded_translation(language),
DataRepr::Bytes => bytes_exceeded_translation(language),
DataRepr::Bits => bits_exceeded_translation(language),
}
}
}
/// Represents a Byte or bit multiple for displaying values in a human-readable format.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ByteMultiple {
/// A Byte
@@ -19,12 +84,6 @@ pub enum ByteMultiple {
PB,
}
impl fmt::Display for ByteMultiple {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self:?}")
}
}
impl ByteMultiple {
pub fn multiplier(self) -> u64 {
match self {
@@ -37,7 +96,7 @@ pub fn multiplier(self) -> u64 {
}
}
fn from_num_bytes(bytes: u128) -> Self {
fn from_amount(bytes: u128) -> Self {
match bytes {
x if (u128::MIN..u128::from(ByteMultiple::KB.multiplier())).contains(&x) => {
ByteMultiple::B
@@ -71,10 +130,14 @@ fn from_num_bytes(bytes: u128) -> Self {
}
pub fn get_char(self) -> String {
self.to_string()
.strip_suffix('B')
.unwrap_or_default()
.to_owned()
match self {
Self::B => String::new(),
Self::KB => "K".to_string(),
Self::MB => "M".to_string(),
Self::GB => "G".to_string(),
Self::TB => "T".to_string(),
Self::PB => "P".to_string(),
}
}
pub fn from_char(ch: char) -> Self {
@@ -88,22 +151,12 @@ pub fn from_char(ch: char) -> Self {
}
}
/// Returns a String representing a quantity of bytes with its proper multiple (B, KB, MB, GB, TB)
pub fn formatted_string(bytes: u128) -> String {
#[allow(clippy::cast_precision_loss)]
let mut n = bytes as f32;
let byte_multiple = ByteMultiple::from_num_bytes(bytes);
#[allow(clippy::cast_precision_loss)]
let multiplier = byte_multiple.multiplier() as f32;
n /= multiplier;
if n > 999.0 && byte_multiple != ByteMultiple::PB {
// this allows representing e.g. 999_999 as 999 KB instead of 1000 KB
n = 999.0;
pub fn pretty_print(&self, repr: DataRepr) -> String {
match repr {
DataRepr::Packets => String::new(),
DataRepr::Bytes => format!("{}B", self.get_char()),
DataRepr::Bits => format!("{}b", self.get_char()),
}
let precision = usize::from(byte_multiple != ByteMultiple::B && n <= 9.95);
format!("{n:.precision$} {byte_multiple}")
}
}

View File

@@ -1,8 +1,8 @@
use crate::Service;
use crate::chart::types::chart_type::ChartType;
use crate::networking::types::address_port_pair::AddressPortPair;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::Host;
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
use crate::utils::types::timestamp::Timestamp;
@@ -65,8 +65,8 @@ pub fn refresh(&mut self, msg: &mut InfoTraffic) {
}
}
pub fn get_thumbnail_data(&self, chart_type: ChartType) -> (u128, u128, u128, u128) {
if chart_type.eq(&ChartType::Bytes) {
pub fn get_thumbnail_data(&self, data_repr: DataRepr) -> (u128, u128, u128, u128) {
if data_repr.eq(&ChartType::Bytes) {
(
self.tot_data_info.incoming_bytes(),
self.tot_data_info.outgoing_bytes(),

View File

@@ -2,10 +2,10 @@
pub mod arp_type;
pub mod asn;
pub mod bogon;
pub mod byte_multiple;
pub mod capture_context;
pub mod data_info;
pub mod data_info_host;
pub mod data_representation;
pub mod filters;
pub mod host;
pub mod host_data_states;

View File

@@ -1,8 +1,8 @@
use crate::InfoTraffic;
use crate::chart::types::chart_type::ChartType;
use crate::networking::types::capture_context::CaptureSource;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::Host;
use crate::networking::types::service::Service;
use crate::notifications::types::logged_notification::{
@@ -31,8 +31,8 @@ pub fn notify_and_log(
let data_info = info_traffic_msg.tot_data_info;
// data threshold
if let Some(threshold) = notifications.data_notification.threshold {
let chart_type = notifications.data_notification.chart_type;
if data_info.tot_data(chart_type) > u128::from(threshold) {
let data_repr = notifications.data_notification.data_repr;
if data_info.tot_data(data_repr) > u128::from(threshold) {
//log this notification
logged_notifications.1 += 1;
if logged_notifications.0.len() >= 30 {
@@ -43,13 +43,13 @@ pub fn notify_and_log(
.push_front(LoggedNotification::DataThresholdExceeded(
DataThresholdExceeded {
id: logged_notifications.1,
chart_type,
data_repr,
threshold: notifications.data_notification.previous_threshold,
data_info,
timestamp: get_formatted_timestamp(timestamp),
is_expanded: false,
hosts: hosts_list(info_traffic_msg, chart_type),
services: services_list(info_traffic_msg, chart_type),
hosts: hosts_list(info_traffic_msg, data_repr),
services: services_list(info_traffic_msg, data_repr),
},
));
if sound_to_play.eq(&Sound::None) {
@@ -98,7 +98,7 @@ pub fn notify_and_log(
logged_notifications.1 - emitted_notifications_prev
}
fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Host, DataInfoHost)> {
fn hosts_list(info_traffic_msg: &InfoTraffic, data_repr: DataRepr) -> Vec<(Host, DataInfoHost)> {
let mut hosts: Vec<(Host, DataInfoHost)> = info_traffic_msg
.hosts
.iter()
@@ -106,7 +106,7 @@ fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Hos
.collect();
hosts.sort_by(|(_, a), (_, b)| {
a.data_info
.compare(&b.data_info, SortType::Descending, chart_type)
.compare(&b.data_info, SortType::Descending, data_repr)
});
let n_entry = min(hosts.len(), 4);
hosts
@@ -117,17 +117,14 @@ fn hosts_list(info_traffic_msg: &InfoTraffic, chart_type: ChartType) -> Vec<(Hos
.collect()
}
fn services_list(
info_traffic_msg: &InfoTraffic,
chart_type: ChartType,
) -> Vec<(Service, DataInfo)> {
fn services_list(info_traffic_msg: &InfoTraffic, data_repr: DataRepr) -> Vec<(Service, DataInfo)> {
let mut services: Vec<(Service, DataInfo)> = info_traffic_msg
.services
.iter()
.filter(|(service, _)| service != &&Service::NotApplicable)
.map(|(s, data)| (*s, *data))
.collect();
services.sort_by(|(_, a), (_, b)| a.compare(b, SortType::Descending, chart_type));
services.sort_by(|(_, a), (_, b)| a.compare(b, SortType::Descending, data_repr));
let n_entry = min(services.len(), 4);
services
.get(..n_entry)

View File

@@ -1,6 +1,6 @@
use crate::chart::types::chart_type::ChartType;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::Host;
use crate::networking::types::service::Service;
@@ -38,7 +38,7 @@ pub fn expand(&mut self, expand: bool) {
#[derive(Clone)]
pub struct DataThresholdExceeded {
pub(crate) id: usize,
pub(crate) chart_type: ChartType,
pub(crate) data_repr: DataRepr,
pub(crate) threshold: u64,
pub(crate) data_info: DataInfo,
pub(crate) timestamp: String,

View File

@@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::ByteMultiple;
use crate::chart::types::chart_type::ChartType;
use crate::networking::types::data_representation::DataRepr;
use crate::notifications::types::sound::Sound;
/// Used to contain the notifications configuration set by the user
@@ -34,7 +34,7 @@ pub enum Notification {
#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug, Copy)]
pub struct DataNotification {
/// Data representation
pub chart_type: ChartType,
pub data_repr: DataRepr,
/// Threshold of received + sent bytes; if exceeded a notification is emitted
pub threshold: Option<u64>,
/// B, KB, MB or GB
@@ -48,7 +48,7 @@ pub struct DataNotification {
impl Default for DataNotification {
fn default() -> Self {
DataNotification {
chart_type: ChartType::Bytes,
data_repr: DataRepr::Bytes,
threshold: None,
byte_multiple: ByteMultiple::KB,
sound: Sound::Pop,

View File

@@ -4,10 +4,11 @@
use crate::networking::types::address_port_pair::AddressPortPair;
use crate::networking::types::data_info::DataInfo;
use crate::networking::types::data_info_host::DataInfoHost;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::host::Host;
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
use crate::report::types::sort_type::SortType;
use crate::{ChartType, InfoTraffic, ReportSortType, Service, Sniffer};
use crate::{InfoTraffic, ReportSortType, Service, Sniffer};
/// Return the elements that satisfy the search constraints and belong to the given page,
/// and the total number of elements which satisfy the search constraints,
@@ -82,12 +83,12 @@ pub fn get_searched_entries(
pub fn get_host_entries(
info_traffic: &InfoTraffic,
chart_type: ChartType,
data_repr: DataRepr,
sort_type: SortType,
) -> Vec<(Host, DataInfoHost)> {
let mut sorted_vec: Vec<(&Host, &DataInfoHost)> = info_traffic.hosts.iter().collect();
sorted_vec.sort_by(|&(_, a), &(_, b)| a.data_info.compare(&b.data_info, sort_type, chart_type));
sorted_vec.sort_by(|&(_, a), &(_, b)| a.data_info.compare(&b.data_info, sort_type, data_repr));
let n_entry = min(sorted_vec.len(), 30);
sorted_vec[0..n_entry]
@@ -98,7 +99,7 @@ pub fn get_host_entries(
pub fn get_service_entries(
info_traffic: &InfoTraffic,
chart_type: ChartType,
data_repr: DataRepr,
sort_type: SortType,
) -> Vec<(Service, DataInfo)> {
let mut sorted_vec: Vec<(&Service, &DataInfo)> = info_traffic
@@ -107,7 +108,7 @@ pub fn get_service_entries(
.filter(|(service, _)| service != &&Service::NotApplicable)
.collect();
sorted_vec.sort_by(|&(_, a), &(_, b)| a.compare(b, sort_type, chart_type));
sorted_vec.sort_by(|&(_, a), &(_, b)| a.compare(b, sort_type, data_repr));
let n_entry = min(sorted_vec.len(), 30);
sorted_vec[0..n_entry]

View File

@@ -1,5 +1,5 @@
use crate::ByteMultiple;
use crate::networking::types::address_port_pair::AddressPortPair;
use crate::networking::types::data_representation::DataRepr;
use crate::networking::types::info_address_port_pair::InfoAddressPortPair;
use crate::report::types::search_parameters::FilterInputType;
use crate::translations::translations::{
@@ -25,6 +25,7 @@ pub enum ReportCol {
DstPort,
Proto,
Service,
Bits,
Bytes,
Packets,
}
@@ -92,8 +93,9 @@ pub(crate) fn get_value(&self, key: &AddressPortPair, val: &InfoAddressPortPair)
}
ReportCol::Proto => key.protocol.to_string(),
ReportCol::Service => val.service.to_string(),
ReportCol::Bytes => ByteMultiple::formatted_string(val.transmitted_bytes),
ReportCol::Packets => val.transmitted_packets.to_string(),
ReportCol::Bits => DataRepr::Bits.formatted_string(val.transmitted_bytes * 8),
ReportCol::Bytes => DataRepr::Bytes.formatted_string(val.transmitted_bytes),
ReportCol::Packets => DataRepr::Packets.formatted_string(val.transmitted_packets),
}
}