1mod cargo_bin_basic;
2mod cargo_lib_basic;
3mod cargo_proc_basic;
4mod universal_default;
5
6pub use cargo_bin_basic::cargo_bin_basic;
7pub use cargo_lib_basic::cargo_lib_basic;
8pub use cargo_proc_basic::cargo_proc_basic;
9use derive_setters::Setters;
10pub use universal_default::universal_default;
11
12use std::{
13 fs,
14 io::Write,
15 path::{Path, PathBuf},
16};
17
18use derive_getters::Getters;
19use serde::{Deserialize, Serialize};
20
21use crate::{
22 SOLARCONFIGNAME, SolarError, ToolTrait,
23 tool::{CargoDeny, Commitalyzer, GithubWorkflows, Licenses, PreCommit, SemverRelease, Vhooks},
24};
25
26use clap::ValueEnum;
27
28#[derive(ValueEnum, Clone, Debug)]
29pub enum ProjConfig {
30 CargoBinBasic,
31 CargoLibBasic,
32 CargoProcBasic,
33 UniversalDefault,
34}
35
36impl ProjConfig {
37 pub fn get(&self) -> Config {
38 match self {
39 Self::CargoBinBasic => cargo_bin_basic(),
40 Self::CargoLibBasic => cargo_lib_basic(),
41 Self::CargoProcBasic => cargo_proc_basic(),
42 Self::UniversalDefault => universal_default(),
43 }
44 }
45}
46
47#[derive(Serialize, Deserialize, Debug, Getters, Setters)]
48pub struct Config {
49 #[serde(skip)]
50 #[setters(rename = "set_path")]
51 path: PathBuf,
52
53 #[setters(rename = "set_vhooks")]
54 vhooks: Option<Vhooks>,
55
56 #[setters(rename = "set_semver_release")]
57 semver_release: Option<SemverRelease>,
58
59 #[setters(rename = "set_pre_commit")]
60 pre_commit: Option<PreCommit>,
61
62 #[setters(rename = "set_licenses")]
63 licenses: Option<Licenses>,
64
65 #[setters(rename = "set_github_workflows")]
66 github_workflows: Option<GithubWorkflows>,
67
68 #[setters(rename = "set_commitalyzer")]
69 commitalyzer: Option<Commitalyzer>,
70
71 #[setters(rename = "set_cargo_deny")]
72 cargo_deny: Option<CargoDeny>,
73}
74
75impl ToolTrait for Config {
76 fn set_dest(&mut self, dest: &Path) {
77 self.on_all(|tool| tool.set_dest(dest));
78 }
79
80 fn act(&mut self, action: &crate::Action, dest: Option<&Path>) -> Result<(), SolarError> {
81 self.try_all(|tool| tool.act(action, dest))?;
82 Ok(())
83 }
84
85 fn install(&mut self) -> Result<(), SolarError> {
86 self.try_all(|tool| tool.install())?;
87 Ok(())
88 }
89
90 fn upgrade(&mut self) -> Result<(), SolarError> {
91 self.try_all(|tool| tool.upgrade())?;
92 Ok(())
93 }
94
95 fn uninstall(&mut self) -> Result<(), SolarError> {
96 self.try_all(|tool| tool.uninstall())?;
97 Ok(())
98 }
99}
100
101impl Config {
102 #[allow(clippy::too_many_arguments)]
103 pub fn new(
104 path: PathBuf,
105 vhooks: Option<Vhooks>,
106 semver_release: Option<SemverRelease>,
107 pre_commit: Option<PreCommit>,
108 licenses: Option<Licenses>,
109 github_workflows: Option<GithubWorkflows>,
110 commitalyzer: Option<Commitalyzer>,
111 cargo_deny: Option<CargoDeny>,
112 ) -> Self {
113 Self {
114 path,
115 vhooks,
116 semver_release,
117 pre_commit,
118 licenses,
119 github_workflows,
120 commitalyzer,
121 cargo_deny,
122 }
123 }
124
125 pub fn new_empty(dest: &Path) -> Self {
126 Self::new(dest.to_path_buf(), None, None, None, None, None, None, None)
127 }
128
129 pub fn on_all<F>(&mut self, mut f: F)
130 where
131 F: FnMut(&mut dyn ToolTrait),
132 {
133 if let Some(tool) = &mut self.vhooks {
134 f(tool);
135 }
136 if let Some(tool) = &mut self.semver_release {
137 f(tool);
138 }
139 if let Some(tool) = &mut self.pre_commit {
140 f(tool);
141 }
142 if let Some(tool) = &mut self.licenses {
143 f(tool);
144 }
145 if let Some(tool) = &mut self.github_workflows {
146 f(tool);
147 }
148 if let Some(tool) = &mut self.commitalyzer {
149 f(tool);
150 }
151 if let Some(tool) = &mut self.cargo_deny {
152 f(tool);
153 }
154 }
155
156 pub fn try_all<F>(&mut self, mut f: F) -> Result<(), SolarError>
157 where
158 F: FnMut(&mut dyn ToolTrait) -> Result<(), SolarError>,
159 {
160 if let Some(tool) = &mut self.vhooks {
161 f(tool)?;
162 }
163 if let Some(tool) = &mut self.semver_release {
164 f(tool)?;
165 }
166 if let Some(tool) = &mut self.pre_commit {
167 f(tool)?;
168 }
169 if let Some(tool) = &mut self.licenses {
170 f(tool)?;
171 }
172 if let Some(tool) = &mut self.github_workflows {
173 f(tool)?;
174 }
175 if let Some(tool) = &mut self.commitalyzer {
176 f(tool)?;
177 }
178 if let Some(tool) = &mut self.cargo_deny {
179 f(tool)?;
180 }
181 Ok(())
182 }
183
184 pub fn load_from_file(file_path: &Path) -> Result<Self, SolarError> {
187 let config_file = fs::read_to_string(file_path)?;
188 let config: Config = serde_json::from_str(&config_file)?;
189 Ok(config.set_path(file_path.to_path_buf()))
190 }
191
192 pub fn load_from(file_path: &Path) -> Result<Self, SolarError> {
193 Self::load_from_file(&file_path.join(SOLARCONFIGNAME))
194 }
195
196 pub fn load_or_default(file_path: &Path) -> Self {
197 Self::load_from(file_path).unwrap_or(Self::new_empty(&file_path.join(SOLARCONFIGNAME)))
198 }
199
200 pub fn save_to_file(&self, file_path: &Path) -> Result<(), SolarError> {
201 if !fs::exists(file_path)? {
202 fs::File::create(file_path)?;
203 }
204 let mut file = fs::File::options()
205 .write(true)
206 .truncate(true)
207 .open(file_path)?;
208 file.write_all(serde_json::to_string(self)?.as_bytes())?;
209 Ok(())
210 }
211
212 pub fn save_to(&self, file_path: &Path) -> Result<(), SolarError> {
213 self.save_to_file(&file_path.join(SOLARCONFIGNAME))
214 }
215
216 pub fn save(&self) -> Result<(), SolarError> {
217 self.save_to_file(&self.path)
218 }
219
220 pub fn is_empty(&self) -> bool {
221 self.vhooks.is_none()
222 && self.semver_release.is_none()
223 && self.pre_commit.is_none()
224 && self.licenses.is_none()
225 && self.github_workflows.is_none()
226 && self.commitalyzer.is_none()
227 && self.cargo_deny.is_none()
228 }
229}