1use std::{
3 fs::{create_dir_all, read_to_string, File},
4 io::Write,
5 path::PathBuf,
6};
7
8use home::home_dir;
9use serde::{Deserialize, Serialize};
10
11use crate::{
12 cli::GitMoverCli, codeberg::config::CodebergConfig, errors::GitMoverError,
13 github::config::GithubConfig, gitlab::config::GitlabConfig,
14};
15
16#[derive(Deserialize, Default, Clone, Debug)]
18pub struct GitMoverConfig {
19 pub config_path: PathBuf,
21
22 pub config_data: ConfigData,
24
25 pub cli_args: GitMoverCli,
27}
28
29#[derive(Deserialize, Serialize, Default, Clone, Debug)]
30pub struct ConfigData {
31 pub gitlab: Option<GitlabConfig>,
33
34 pub github: Option<GithubConfig>,
36
37 pub codeberg: Option<CodebergConfig>,
39}
40
41impl GitMoverConfig {
42 pub fn try_new(cli_args: GitMoverCli) -> Result<Self, GitMoverError> {
46 let config_path = match cli_args.config.clone() {
47 Some(p) => p,
48 None => Self::get_config_path()?,
49 };
50 let contents = read_to_string(config_path.clone())
51 .map_err(|e| GitMoverError::new_with_source("Unable to open", e))?;
52 let config_data = toml::from_str(&contents)?;
53 Ok(GitMoverConfig {
54 config_path,
55 cli_args,
56 config_data,
57 })
58 }
59
60 pub fn save(&self) -> Result<(), GitMoverError> {
64 let config_str = toml::to_string(&self.config_data)
65 .map_err(|e| GitMoverError::new_with_source("Unable to serialize config", e))?;
66 let mut file = File::create(&self.config_path)
67 .map_err(|e| GitMoverError::new_with_source("Unable to create config file", e))?;
68 file.write_all(config_str.as_bytes())
69 .map_err(|e| GitMoverError::new_with_source("Unable to write to config file", e))
70 }
71
72 pub fn get_config_path() -> Result<PathBuf, GitMoverError> {
76 let home_dir = match home_dir() {
77 Some(path) if !path.as_os_str().is_empty() => path,
78 _ => return Err("Unable to get your home dir! home::home_dir() isn't working".into()),
79 };
80 let config_directory = home_dir.join(".config").join(".git-mover");
81 let config_path = config_directory.join("config.toml");
82 create_dir_all(config_directory)
83 .map_err(|e| GitMoverError::new_with_source("Unable to create config dir", e))?;
84 if !config_path.exists() {
85 let mut file = File::create(&config_path)
86 .map_err(|e| GitMoverError::new_with_source("Unable to create config file", e))?;
87 file.write_all(b"")
88 .map_err(|e| GitMoverError::new_with_source("Unable to write to config file", e))?;
89 }
90 Ok(config_path)
91 }
92
93 pub fn update(
97 &mut self,
98 updater_fn: impl FnOnce(&mut ConfigData),
99 ) -> Result<(), GitMoverError> {
100 updater_fn(&mut self.config_data);
101 self.save()?;
102 Ok(())
103 }
104}