highlighted_match_with_paths.rs

 1use ui::{HighlightedLabel, prelude::*};
 2
 3#[derive(Clone)]
 4pub struct HighlightedMatchWithPaths {
 5    pub match_label: HighlightedMatch,
 6    pub paths: Vec<HighlightedMatch>,
 7}
 8
 9#[derive(Debug, Clone, IntoElement)]
10pub struct HighlightedMatch {
11    pub text: String,
12    pub highlight_positions: Vec<usize>,
13    pub char_count: usize,
14    pub color: Color,
15}
16
17impl HighlightedMatch {
18    pub fn join(components: impl Iterator<Item = Self>, separator: &str) -> Self {
19        let mut char_count = 0;
20        let separator_char_count = separator.chars().count();
21        let mut text = String::new();
22        let mut highlight_positions = Vec::new();
23        for component in components {
24            if char_count != 0 {
25                text.push_str(separator);
26                char_count += separator_char_count;
27            }
28
29            highlight_positions.extend(
30                component
31                    .highlight_positions
32                    .iter()
33                    .map(|position| position + char_count),
34            );
35            text.push_str(&component.text);
36            char_count += component.text.chars().count();
37        }
38
39        Self {
40            text,
41            highlight_positions,
42            char_count,
43            color: Color::Default,
44        }
45    }
46
47    pub fn color(self, color: Color) -> Self {
48        Self { color, ..self }
49    }
50}
51impl RenderOnce for HighlightedMatch {
52    fn render(self, _window: &mut Window, _: &mut App) -> impl IntoElement {
53        HighlightedLabel::new(self.text, self.highlight_positions).color(self.color)
54    }
55}
56
57impl HighlightedMatchWithPaths {
58    pub fn render_paths_children(&mut self, element: Div) -> Div {
59        element.children(self.paths.clone().into_iter().map(|path| {
60            HighlightedLabel::new(path.text, path.highlight_positions)
61                .size(LabelSize::Small)
62                .color(Color::Muted)
63        }))
64    }
65}
66
67impl RenderOnce for HighlightedMatchWithPaths {
68    fn render(mut self, _window: &mut Window, _: &mut App) -> impl IntoElement {
69        v_flex()
70            .child(self.match_label.clone())
71            .when(!self.paths.is_empty(), |this| {
72                self.render_paths_children(this)
73            })
74    }
75}