dns_geolocation_checker/
configs_parser.rs1#![allow(dead_code)]
2
3use serde::Deserialize;
4use std::{collections::HashMap, fs};
5
6use crate::ip_geo_client::IpGeoProviderType;
7
8#[derive(Default, Debug, Clone, Deserialize)]
10pub struct Config {
11 #[serde(default)]
13 pub ip_geo_provider: IpGeoProviderType,
14 #[serde(default)]
15 pub mmdb_path: Option<String>,
16 pub test_subnets: HashMap<String, RoutingCountryConfig>,
18 pub domain: Vec<DomainConfig>,
20}
21
22#[derive(Default, Debug, Clone, Deserialize)]
24pub struct DomainConfig {
25 pub host: String,
27 pub geo_routing: Vec<String>,
29}
30
31#[derive(Default, Debug, Clone, Deserialize)]
33pub struct RoutingCountryConfig {
34 pub subnets: Vec<String>,
36}
37
38#[derive(Clone)]
39pub struct ConfigParser<T: for<'a> Deserialize<'a>> {
40 config: T,
42}
43
44impl<C: for<'a> Deserialize<'a>> ConfigParser<C> {
45 pub fn parse(contents: String) -> C {
69 toml::from_str(&contents).unwrap()
70 }
71}
72
73impl ConfigParser<Config> {
74 pub fn new_with_path<T: ToString>(path: T) -> ConfigParser<Config> {
76 let contents =
77 fs::read_to_string(&path.to_string()).expect("Should have been able to read the file");
78
79 ConfigParser {
80 config: ConfigParser::parse(contents),
81 }
82 }
83
84 pub fn config(&self) -> &Config {
86 &self.config
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use std::fs;
94 const TEMP_DIR_PATH: &'static str = "./temp";
95 const TEMP_PATH: &'static str = "./temp/domain.toml";
96
97 fn setup() {
98 if fs::read_dir(TEMP_DIR_PATH).is_err() {
99 fs::create_dir_all(TEMP_DIR_PATH).expect("Unable to create directory");
100 }
101
102 let test_config = r#"
103 [test_subnets]
104 us = { subnets = ["44.208.193.0/24"] }
105
106 [[domain]]
107 host = "google.com"
108 geo_routing = ["us"]
109 "#
110 .trim();
111
112 fs::write(TEMP_PATH, test_config).expect("Unable to write file");
113 }
114
115 fn teardown() {
116 fs::remove_dir_all(TEMP_DIR_PATH).expect("Unable to remove directory");
117 }
118
119 #[test]
120 fn test_new_with_path() {
121 setup();
122
123 let parser = ConfigParser::new_with_path(TEMP_PATH);
124 let config = parser.config();
125 assert_eq!(config.domain.len(), 1);
126 assert_eq!(config.test_subnets.len(), 1);
127 assert_eq!(config.domain.len(), 1);
128 assert_eq!(config.test_subnets.len(), 1);
129 assert_eq!(config.domain[0].host, "google.com");
130 assert_eq!(
131 config.test_subnets.get("us").unwrap().subnets[0],
132 "44.208.193.0/24"
133 );
134
135 teardown();
136 }
137
138 #[test]
139 fn test_parse() {
140 let test_config = r#"
141 [test_subnets]
142 us = { subnets = ["44.208.193.0/24"] }
143
144 [[domain]]
145 host = "google.com"
146 geo_routing = ["us"]
147 "#;
148
149 let config: Config = ConfigParser::parse(test_config.to_string());
150 assert_eq!(config.domain.len(), 1);
151 assert_eq!(config.test_subnets.len(), 1);
152 assert_eq!(config.domain[0].host, "google.com");
153 assert_eq!(
154 config.test_subnets.get("us").unwrap().subnets[0],
155 "44.208.193.0/24"
156 );
157 }
158}