1use std::io;
2use std::fs;
3use std::error;
4
5use io::Read;
6use io::Write;
7use io::ErrorKind;
8
9use crate::checker;
10
11use serde::{Serialize, Deserialize};
12
13#[derive(Serialize, Deserialize, Debug)]
14pub struct Config {
15 pub api_key: String
16}
17
18impl std::default::Default for Config {
19 fn default() -> Self {
20 Self {
21 api_key: "".into()
22 }
23 }
24}
25
26
27
28pub fn load_config() -> Result<Config, Box<dyn error::Error>> {
29 let loaded_config = get_config();
30
31 match loaded_config {
32 Ok(config) => {
33 match checker::verify_cmc_api_key_format(&config.api_key) {
34 Ok(()) => return Ok(config),
35 Err(e) => {
36 println!("{}", e);
37 return Err(e.into());
38 }
39 }
40 },
41 Err(e) => {
42 match e.kind() {
43 ErrorKind::NotFound => {
44 let config = read_config()?;
45 write_config(&config)?;
46 return load_config();
47 }
48 _ => return Err(e.into())
49 }
50 }
51 }
52}
53
54fn read_config() -> Result<Config, Box<dyn error::Error>> {
55 let mut buffer = String::new();
56 let stdin = io::stdin();
57
58 println!("Please enter your CMC API Key:");
59 stdin.read_line(&mut buffer)?;
60
61 return Ok(Config {api_key: buffer});
62}
63
64fn write_config(c: &Config) -> io::Result<()> {
65 let mut file = fs::File::create("config.json")?;
66 let serialized_config = serde_json::to_string_pretty(&c)?;
67
68 file.write_all(serialized_config.as_bytes())?;
69
70 return Ok(());
71}
72
73fn get_config() -> io::Result<Config> {
74 let mut file = fs::File::open("config.json")?;
75 let mut content = String::new();
76
77 file.read_to_string(&mut content)?;
78 let deserialized_content = serde_json::from_str::<Config>(&content);
79
80 match deserialized_content {
81 Ok(config) => return Ok(config),
82 Err(e) => {
83 println!("Incorrect config file format, will re-generate the default config file.");
84 write_config(&Config::default())?;
85 return Err(e.into());
86 }
87 }
88}