malwaredb 0.3.5

Service for storing malicious, benign, or unknown files and related metadata and relationships.
// SPDX-License-Identifier: Apache-2.0

use malwaredb_server::State;
use malwaredb_server::db::admin::Group;

use std::sync::Arc;

use anyhow::Result;
use eframe::egui::Id;

const COLUMN_HEADERS: [&str; 7] = [
    "ID",
    "Name",
    "Description",
    "Parent",
    "Members",
    "Files",
    "Sources",
];

/// Groups table
#[derive(Debug, Clone)]
pub struct GroupTable {
    #[allow(dead_code)]
    state: Arc<State>,

    groups: Vec<Group>,
}

impl GroupTable {
    pub async fn new(state: Arc<State>) -> Result<Self> {
        let groups = state.db_type.list_groups().await?;
        Ok(Self { state, groups })
    }

    pub fn ui(&mut self, ui: &mut eframe::egui::Ui) {
        let id_salt = Id::new("group_table");

        let table = egui_table::Table::new()
            .id_salt(id_salt)
            .auto_size_mode(egui_table::AutoSizeMode::OnParentResize)
            .num_rows(self.groups.len() as u64)
            .columns(
                (0..COLUMN_HEADERS.len())
                    .map(|_| egui_table::Column::new(100.0).resizable(true))
                    .collect::<Vec<_>>(),
            );

        table.show(ui, self);
    }
}

impl egui_table::TableDelegate for GroupTable {
    fn header_cell_ui(&mut self, ui: &mut eframe::egui::Ui, cell: &egui_table::HeaderCellInfo) {
        if let Some(header) = COLUMN_HEADERS.get(cell.group_index) {
            ui.label(*header);
        }
    }

    fn cell_ui(&mut self, ui: &mut eframe::egui::Ui, cell: &egui_table::CellInfo) {
        let Some(group) = usize::try_from(cell.row_nr)
            .ok()
            .and_then(|row| self.groups.get(row))
        else {
            return;
        };

        let text: std::borrow::Cow<str> = match cell.col_nr {
            0 => group.id.to_string().into(),
            1 => group.name.as_str().into(),
            2 => group.description.as_deref().unwrap_or_default().into(),
            3 => group.parent.as_deref().unwrap_or_default().into(),
            4 => group.members.len().to_string().into(),
            5 => group.files.to_string().into(),
            6 => group.sources.len().to_string().into(),
            _ => "".into(),
        };
        ui.label(text.as_ref());
    }
}