Skip to main content

ghostscope_ui/events/
source_path.rs

1/// Source path information for display (shared between UI and runtime)
2#[derive(Debug, Clone)]
3pub struct SourcePathInfo {
4    pub substitutions: Vec<PathSubstitution>,
5    pub search_dirs: Vec<String>,
6    pub runtime_substitution_count: usize,
7    pub runtime_search_dir_count: usize,
8    pub config_substitution_count: usize,
9    pub config_search_dir_count: usize,
10}
11
12impl SourcePathInfo {
13    /// Format for display in command panel
14    pub fn format_for_display(&self) -> String {
15        let mut output = String::new();
16
17        output.push_str("šŸ—‚ļø  Source Path Configuration:\n\n");
18
19        // Path substitutions
20        if self.substitutions.is_empty() {
21            output.push_str("Path Substitutions: (none)\n");
22        } else {
23            output.push_str(&format!(
24                "Path Substitutions ({}):\n",
25                self.substitutions.len()
26            ));
27            for (i, sub) in self.substitutions.iter().enumerate() {
28                let marker = if i < self.runtime_substitution_count {
29                    "[runtime]"
30                } else {
31                    "[config] "
32                };
33                output.push_str(&format!("  {} {} -> {}\n", marker, sub.from, sub.to));
34            }
35        }
36
37        output.push('\n');
38
39        // Search directories
40        if self.search_dirs.is_empty() {
41            output.push_str("Search Directories: (none)\n");
42        } else {
43            output.push_str(&format!(
44                "Search Directories ({}):\n",
45                self.search_dirs.len()
46            ));
47            for (i, dir) in self.search_dirs.iter().enumerate() {
48                let marker = if i < self.runtime_search_dir_count {
49                    "[runtime]"
50                } else {
51                    "[config] "
52                };
53                output.push_str(&format!("  {marker} {dir}\n"));
54            }
55        }
56
57        output.push_str("\nšŸ’” Runtime rules take precedence over config file rules.\n");
58        output.push_str(
59            "šŸ’” Use 'srcpath clear' to remove runtime rules, 'srcpath reset' to reset to config.\n",
60        );
61
62        output
63    }
64
65    /// Styled version for display
66    pub fn format_for_display_styled(&self) -> Vec<ratatui::text::Line<'static>> {
67        use crate::components::command_panel::style_builder::{StylePresets, StyledLineBuilder};
68        use ratatui::text::Line;
69
70        let mut lines = Vec::new();
71
72        // Title
73        lines.push(
74            StyledLineBuilder::new()
75                .title("šŸ—‚ļø  Source Path Configuration:")
76                .build(),
77        );
78        lines.push(Line::from(""));
79
80        // Path substitutions
81        if self.substitutions.is_empty() {
82            lines.push(
83                StyledLineBuilder::new()
84                    .key("Path Substitutions:")
85                    .text(" (none)")
86                    .build(),
87            );
88        } else {
89            lines.push(
90                StyledLineBuilder::new()
91                    .key(format!(
92                        "Path Substitutions ({}):",
93                        self.substitutions.len()
94                    ))
95                    .build(),
96            );
97            for (i, sub) in self.substitutions.iter().enumerate() {
98                let marker = if i < self.runtime_substitution_count {
99                    "[runtime]"
100                } else {
101                    "[config] "
102                };
103                lines.push(
104                    StyledLineBuilder::new()
105                        .text("  ")
106                        .styled(marker, StylePresets::MARKER)
107                        .text(" ")
108                        .value(&sub.from)
109                        .styled(" -> ", StylePresets::TREE)
110                        .styled(&sub.to, StylePresets::KEY)
111                        .build(),
112                );
113            }
114        }
115
116        lines.push(Line::from(""));
117
118        // Search directories
119        if self.search_dirs.is_empty() {
120            lines.push(
121                StyledLineBuilder::new()
122                    .key("Search Directories:")
123                    .text(" (none)")
124                    .build(),
125            );
126        } else {
127            lines.push(
128                StyledLineBuilder::new()
129                    .key(format!("Search Directories ({}):", self.search_dirs.len()))
130                    .build(),
131            );
132            for (i, dir) in self.search_dirs.iter().enumerate() {
133                let marker = if i < self.runtime_search_dir_count {
134                    "[runtime]"
135                } else {
136                    "[config] "
137                };
138                lines.push(
139                    StyledLineBuilder::new()
140                        .text("  ")
141                        .styled(marker, StylePresets::MARKER)
142                        .text(" ")
143                        .value(dir)
144                        .build(),
145                );
146            }
147        }
148
149        lines.push(Line::from(""));
150        lines.push(
151            StyledLineBuilder::new()
152                .styled(
153                    "šŸ’” Runtime rules take precedence over config file rules.",
154                    StylePresets::TIP,
155                )
156                .build(),
157        );
158        lines.push(
159            StyledLineBuilder::new()
160                .styled(
161                    "šŸ’” Use 'srcpath clear' to remove runtime rules, 'srcpath reset' to reset to config.",
162                    StylePresets::TIP,
163                )
164                .build(),
165        );
166
167        lines
168    }
169}
170
171/// Path substitution rule (shared definition)
172#[derive(Debug, Clone, PartialEq, Eq)]
173pub struct PathSubstitution {
174    pub from: String,
175    pub to: String,
176}