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, github::config::GithubConfig,
13 gitlab::config::GitlabConfig,
14};
15
16#[derive(Deserialize, Default, Clone, Debug)]
18pub struct Config {
19 pub debug: u8,
21
22 pub config_path: PathBuf,
24
25 pub config_data: ConfigData,
27
28 pub cli_args: GitMoverCli,
30}
31
32#[derive(Deserialize, Serialize, Default, Clone, Debug)]
33pub struct ConfigData {
34 pub gitlab: Option<GitlabConfig>,
36
37 pub github: Option<GithubConfig>,
39
40 pub codeberg: Option<CodebergConfig>,
42}
43
44impl Config {
45 fn parse_config(str_config: &str, config_path: PathBuf, cli_args: GitMoverCli) -> Config {
47 Config {
48 debug: cli_args.verbose,
49 config_path,
50 cli_args,
51 config_data: match toml::from_str(str_config) {
52 Ok(config) => config,
53 Err(e) => {
54 eprintln!("Unable to parse config file: {e}");
55 eprintln!("Using default config");
56 ConfigData::default()
57 }
58 },
59 }
60 }
61
62 pub fn new(cli_args: GitMoverCli) -> Config {
66 let config_path = Config::get_config_path();
67 let contents = read_to_string(config_path.clone())
68 .unwrap_or_else(|_| panic!("Unable to open {config_path:?}"));
69 Config::parse_config(&contents, config_path, cli_args)
70 }
71
72 pub fn save(&self) {
76 let config_str = toml::to_string(&self.config_data).expect("Unable to serialize config");
77 let mut file = File::create(&self.config_path).expect("Unable to create config file");
78 file.write_all(config_str.as_bytes())
79 .expect("Unable to write to config file");
80 }
81
82 pub fn new_from_path(cli_args: GitMoverCli, custom_path: &PathBuf) -> Config {
86 let contents = read_to_string(custom_path.clone())
87 .unwrap_or_else(|_| panic!("Unable to open {custom_path:?}"));
88 Config::parse_config(&contents, custom_path.clone(), cli_args)
89 }
90
91 pub fn set_debug(mut self, value: u8) -> Self {
93 self.debug = value;
94 self
95 }
96
97 pub fn get_config_path() -> PathBuf {
101 let home_dir = match home_dir() {
102 Some(path) if !path.as_os_str().is_empty() => Ok(path),
103 _ => Err(()),
104 }
105 .expect("Unable to get your home dir! home::home_dir() isn't working");
106 let config_directory = home_dir.join(".config").join(".git-mover");
107 let config_path = config_directory.join("config.toml");
108 create_dir_all(config_directory).expect("Unable to create config dir");
109 if !config_path.exists() {
110 let mut file = File::create(&config_path).expect("Unable to create config file");
111 file.write_all(b"").expect("Unable to write to config file");
112 }
113 config_path
114 }
115
116 pub fn update(&mut self, updater_fn: impl FnOnce(&mut ConfigData) -> &mut ConfigData) {
118 updater_fn(&mut self.config_data);
119 self.save();
120 }
121}