1use crate::{
2 CommandConfig, FilterConfig, ProviderConfig, RazConfig, UiConfig,
3 global::GlobalConfig,
4 override_config::{CommandOverride, OverrideCollection},
5 workspace::WorkspaceConfig,
6};
7use std::path::PathBuf;
8
9#[derive(Debug, Clone)]
10pub struct EffectiveConfig {
11 pub raz: RazConfig,
12 pub providers_config: ProviderConfig,
13 pub filters: FilterConfig,
14 pub ui: UiConfig,
15 pub commands: Vec<CommandConfig>,
16 pub overrides: OverrideCollection,
17}
18
19impl EffectiveConfig {
20 pub fn new(global: GlobalConfig, workspace: Option<WorkspaceConfig>) -> Self {
21 let mut effective = Self::from_global(global);
22
23 if let Some(workspace) = workspace {
24 effective.merge_workspace(workspace);
25 }
26
27 effective
28 }
29
30 fn from_global(global: GlobalConfig) -> Self {
31 Self {
32 raz: global.raz,
33 providers_config: global.providers_config.unwrap_or_default(),
34 filters: global.filters.unwrap_or_else(|| FilterConfig {
35 priority_commands: vec![],
36 ignore_commands: vec![],
37 auto_fix: Some(false),
38 show_warnings: Some(true),
39 }),
40 ui: global.ui.unwrap_or_else(|| UiConfig {
41 color: Some(true),
42 progress: Some(true),
43 verbose: Some(false),
44 format: Some("default".to_string()),
45 }),
46 commands: global.commands.unwrap_or_default(),
47 overrides: global.saved_overrides.unwrap_or_default(),
48 }
49 }
50
51 fn merge_workspace(&mut self, workspace: WorkspaceConfig) {
52 if let Some(raz_config) = workspace.raz {
53 if raz_config.enabled != self.raz.enabled {
54 self.raz.enabled = raz_config.enabled;
55 }
56
57 if !raz_config.providers.is_empty() {
58 self.raz.providers = raz_config.providers;
59 }
60
61 if raz_config.cache_dir.is_some() {
62 self.raz.cache_dir = raz_config.cache_dir;
63 }
64
65 if raz_config.cache_ttl.is_some() {
66 self.raz.cache_ttl = raz_config.cache_ttl;
67 }
68
69 if raz_config.parallel_execution.is_some() {
70 self.raz.parallel_execution = raz_config.parallel_execution;
71 }
72
73 if raz_config.max_concurrent_jobs.is_some() {
74 self.raz.max_concurrent_jobs = raz_config.max_concurrent_jobs;
75 }
76 }
77
78 if let Some(providers) = workspace.providers_config {
79 self.merge_provider_config(providers);
80 }
81
82 if let Some(filters) = workspace.filters {
83 self.merge_filter_config(filters);
84 }
85
86 if let Some(ui) = workspace.ui {
87 self.merge_ui_config(ui);
88 }
89
90 if let Some(mut commands) = workspace.commands {
91 self.commands.append(&mut commands);
92 }
93
94 if let Some(overrides) = workspace.overrides {
95 for (key, override_config) in overrides.overrides {
96 self.overrides.overrides.insert(key, override_config);
97 }
98 }
99 }
100
101 fn merge_provider_config(&mut self, providers: ProviderConfig) {
102 if providers.cargo.is_some() {
103 self.providers_config.cargo = providers.cargo;
104 }
105
106 if providers.rustc.is_some() {
107 self.providers_config.rustc = providers.rustc;
108 }
109
110 if providers.leptos.is_some() {
111 self.providers_config.leptos = providers.leptos;
112 }
113
114 if providers.dioxus.is_some() {
115 self.providers_config.dioxus = providers.dioxus;
116 }
117
118 if providers.bevy.is_some() {
119 self.providers_config.bevy = providers.bevy;
120 }
121
122 if providers.custom.is_some() {
123 self.providers_config.custom = providers.custom;
124 }
125 }
126
127 fn merge_filter_config(&mut self, filters: FilterConfig) {
128 if !filters.priority_commands.is_empty() {
129 self.filters.priority_commands = filters.priority_commands;
130 }
131
132 if !filters.ignore_commands.is_empty() {
133 self.filters.ignore_commands = filters.ignore_commands;
134 }
135
136 if filters.auto_fix.is_some() {
137 self.filters.auto_fix = filters.auto_fix;
138 }
139
140 if filters.show_warnings.is_some() {
141 self.filters.show_warnings = filters.show_warnings;
142 }
143 }
144
145 fn merge_ui_config(&mut self, ui: UiConfig) {
146 if ui.color.is_some() {
147 self.ui.color = ui.color;
148 }
149
150 if ui.progress.is_some() {
151 self.ui.progress = ui.progress;
152 }
153
154 if ui.verbose.is_some() {
155 self.ui.verbose = ui.verbose;
156 }
157
158 if ui.format.is_some() {
159 self.ui.format = ui.format;
160 }
161 }
162
163 pub fn apply_runtime_override(&mut self, override_config: CommandOverride) {
164 let key = override_config.generate_key();
165 self.overrides.overrides.insert(key, override_config);
166 }
167
168 pub fn find_override(
169 &self,
170 file: Option<&PathBuf>,
171 function: Option<&str>,
172 line: Option<usize>,
173 ) -> Option<&CommandOverride> {
174 self.overrides.find_best_match(file, function, line)
175 }
176
177 pub fn is_provider_enabled(&self, provider: &str) -> bool {
178 self.raz.providers.iter().any(|p| p == provider)
179 }
180
181 pub fn get_provider_config(&self, provider: &str) -> Option<&toml::Value> {
182 match provider {
183 "cargo" => self.providers_config.cargo.as_ref(),
184 "rustc" => self.providers_config.rustc.as_ref(),
185 "leptos" => self.providers_config.leptos.as_ref(),
186 "dioxus" => self.providers_config.dioxus.as_ref(),
187 "bevy" => self.providers_config.bevy.as_ref(),
188 _ => self.providers_config.custom.as_ref(),
189 }
190 }
191
192 pub fn should_ignore_command(&self, command: &str) -> bool {
193 self.filters.ignore_commands.iter().any(|c| c == command)
194 }
195
196 pub fn is_priority_command(&self, command: &str) -> bool {
197 self.filters.priority_commands.iter().any(|c| c == command)
198 }
199}