highlighted_match_with_paths.rs

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