orbit-tui 1.2.0

Terminal UI for AWS - navigate, observe, and manage AWS resources
use fuzzy_matcher::{skim::SkimMatcherV2, FuzzyMatcher};
use ratatui::{
    style::Style,
    text::{Line, Span},
    widgets::Cell,
};

pub fn fuzzy_cell(
    display_value: &str,
    query: &str,
    matcher: &SkimMatcherV2,
    base_style: Style,
    match_style: Style,
) -> Cell<'static> {
    if query.is_empty() {
        return Cell::from(format!(" {}", display_value)).style(base_style);
    }

    let Some((_score, indices)) = matcher.fuzzy_indices(display_value, query) else {
        return Cell::from(format!(" {}", display_value)).style(base_style);
    };

    if indices.is_empty() {
        return Cell::from(format!(" {}", display_value)).style(base_style);
    }

    let mut spans = vec![Span::styled(" ", base_style)];
    let mut current_segment = String::new();
    let mut is_matching_segment = false;
    let matched_char_indices: std::collections::HashSet<usize> = indices.into_iter().collect();

    for (char_idx, char) in display_value.chars().enumerate() {
        let is_current_char_a_match = matched_char_indices.contains(&char_idx);

        if char_idx == 0 {
            is_matching_segment = is_current_char_a_match;
        }

        if is_current_char_a_match != is_matching_segment {
            let style = if is_matching_segment {
                match_style
            } else {
                base_style
            };
            spans.push(Span::styled(current_segment, style));
            current_segment = String::new();
            is_matching_segment = is_current_char_a_match;
        }

        current_segment.push(char);
    }

    if !current_segment.is_empty() {
        let style = if is_matching_segment {
            match_style
        } else {
            base_style
        };
        spans.push(Span::styled(current_segment, style));
    }

    Cell::from(Line::from(spans))
}