currency_conversion_cli/
config.rs1use std::{io::Stdin, path::PathBuf};
2
3use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
8pub struct Config {
9 pub api_key: String,
11 pub base: String,
13 pub symbols_endpoint_url: String,
15 pub latest_endpoint_url: String,
17 pub symbols_file_path: String,
19 pub conversion_rates_file_path: String,
21}
22
23#[cfg(not(tarpaulin_include))]
24impl Default for Config {
25 fn default() -> Self {
26 let homedir = home::home_dir().unwrap();
28
29 let mut symbols_file_path = PathBuf::new();
30 symbols_file_path.push(&homedir);
31 symbols_file_path.push(".currency-conversion-cli/symbols.tsv");
32
33 let mut conversion_rates_file_path = PathBuf::new();
34 conversion_rates_file_path.push(&homedir);
35 conversion_rates_file_path.push(".currency-conversion-cli/conversion_rates.tsv");
36
37 Config {
38 api_key: "#INSERT_API_KEY_HERE#".to_string(),
39 base: "EUR".to_string(),
40 symbols_file_path: symbols_file_path.to_string_lossy().into_owned(),
44 conversion_rates_file_path: conversion_rates_file_path.to_string_lossy().into_owned(),
45 latest_endpoint_url:
46 "http://api.exchangeratesapi.io/v1/latest?access_key={api_key}&base={base}"
47 .to_string(),
48 symbols_endpoint_url: "http://api.exchangeratesapi.io/v1/symbols?access_key={api_key}"
49 .to_string(),
50 }
51 }
52}
53
54#[cfg(not(tarpaulin_include))]
55impl Config {
56 pub fn prompt_config(&self) -> Result<Config> {
57 let mut res = Config::default();
58 let stdin = std::io::stdin();
59 let mut buffer = String::new();
60 println!("Initialization of config file");
61
62 println!(
64 "api key (required exchange rates api key)(current : {}) : ",
65 self.api_key
66 );
67 stdin.read_line(&mut buffer)?;
68 if !buffer.trim().is_empty() {
69 res.api_key.clone_from(&buffer.trim().to_string());
70 } else if self.api_key != "#INSERT_API_KEY_HERE#" {
71 res.api_key.clone_from(&self.api_key);
72 } else {
73 bail!("API key must be provided !")
74 }
75
76 res.base
78 .clone_from(&prompt_string(&stdin, "base currency", &self.base)?);
79 res.symbols_file_path.clone_from(&prompt_string(
81 &stdin,
82 "currency symbols file path",
83 &self.symbols_file_path,
84 )?);
85 res.symbols_endpoint_url.clone_from(&prompt_string(
87 &stdin,
88 "currency symbols endpoint URL",
89 &self.symbols_endpoint_url,
90 )?);
91 res.conversion_rates_file_path.clone_from(&prompt_string(
93 &stdin,
94 "conversion rates file path",
95 &self.conversion_rates_file_path,
96 )?);
97 res.latest_endpoint_url.clone_from(&prompt_string(
99 &stdin,
100 "conversion rates endpoint URL",
101 &self.latest_endpoint_url,
102 )?);
103
104 Ok(res)
105 }
106}
107
108#[cfg(not(tarpaulin_include))]
109fn prompt_string(stdin: &Stdin, text: &str, current_value: &String) -> Result<String> {
110 println!("{text} (current : {current_value}) : ");
111 let mut buffer = String::new();
112 stdin.read_line(&mut buffer)?;
113 if buffer.trim().is_empty() {
114 return Ok(current_value.clone());
115 }
116
117 Ok(buffer.trim().to_string())
118}